RxSwift快速指南(二)

Transform

接觸過FP的應(yīng)該都知道m(xù)ap偎行,RxSwift也提供對應(yīng)的方法將Element進行變形总滩,主要的方法有buffer, flatMap, flatMapFirst, flatMapLatest, map, scanwindow拦盹, 用的比較多的是mapflatMap

map

let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
    .map { "\($0)\($0)" }
    .subscribeNext { print($0) }
    .addDisposableTo(disposeBag)

根據(jù)map的定義:

public func map<R>(selector: E throws -> R) -> Observable<R> {
    return self.asObservable().composeMap(selector)
}

selector這個closure負(fù)責(zé)將E轉(zhuǎn)換為R倒慧,而E這里被定義為Observable.of(1, 2, 3)的Int掖举,每個元素會被轉(zhuǎn)換為String。

flatMap

let disposeBag = DisposeBag()
let sequenceInt = Observable.of(1, 2, 3)
let sequenceString = Observable.of("A", "B", "C", "D")

sequenceInt.flatMap { _ in
        return sequenceString
    }
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

flatMap的定義:

public func flatMap<O: ObservableConvertibleType>(selector: (E) throws -> O) -> Observable<O.E> {
    return FlatMap(source: asObservable(), selector: selector)
}

來看看Rx官方給出的描述:

map flatMap
Transform the items emitted by an Observable by applying a function to each item Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable

mapflatMap的區(qū)別在于map的selector將用于Observable中的每一個Element首妖,操作完成后偎漫,Element的數(shù)量和源Observable中的是一樣的,而flatMap的selector的調(diào)用次數(shù)和源Element數(shù)量一致有缆,但是由于selector的返回值為一個Observable象踊,所以在操作完成后,得到的Elements為源Element數(shù)量*selector返回的Observable的Element數(shù)量棚壁,然后將所有Element放入一個Observable中杯矩,類似于[[1, 2], [2, 3], [3, 4]] -> [1, 2, 2, 3, 3, 4]

flatMap

flatMapLatest

比起mapflatMap袖外,要稍微難理解一點:

let disposeBag = DisposeBag()

[1, 2, 3].toObservable()
    .flatMapLatest { value  in
        return ["\(value)a", "\(value)b"].toObservable()
    }
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

根據(jù)RxJS flatMapLatest這個代碼期望的結(jié)果是(RxSwift和Rx系的其他語句具有相似接口史隆,其中RxJava對應(yīng)的方法是switchMap,在RxJS Source Code也能發(fā)現(xiàn)其實它和switchMap是一個函數(shù)):

Next(1a)
Next(2a)
Next(3a)
Next(3b)
Completed

但是實際上得到的輸出結(jié)果是:

Next(1a)
Next(1b)
Next(2a)
Next(2b)
Next(3a)
Next(3b)
Completed

出現(xiàn)這種情況的原因在github的Get Start有解釋曼验,問題出現(xiàn)在selector中的toObservable泌射,它的實現(xiàn)使用了Sequence:

public func toObservable(scheduler: ImmediateSchedulerType? = nil) -> Observable<Generator.Element> {
    return Sequence(elements: self, scheduler: scheduler)
}

Sequence其實是一個同步隊列的實現(xiàn),在subscribe調(diào)用前會生成Next和Completed鬓照,因為無論哪種disposable被返回熔酷,生成elements的過程都不能被打斷。在這種情況下豺裆,flatMapLatestflatMap的輸出結(jié)果一樣拒秘。

期望的版本:

let disposeBag = DisposeBag()
var charValues: [Variable<Character>] = [Variable("a"), Variable("a"), Variable("a")]

[0, 1, 2].toObservable()
    .flatMapLatest { value -> Observable<Character> in
        print("Int value: \(value)")
        return charValues[value].asObservable()
    }
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

charValues[2].value = "b"
charValues[0].value = "c"   // nothing happen
charValues[1].value = "d"   // nothing happen
flatMapLatest

flatMap一樣,flatMapLatest也會新生成一個Observable的隊列留储,但不同的是它不會合并所有的新Observable中的Element翼抠,它會switch到最后一個Observable上(switchMap這個名字感覺更容易讓人理解一點),先前建立的Observable將不再被監(jiān)聽获讳,所以代碼中charValues只有最后一個Observable還在被subscribe。

scan

let disposeBag = DisposeBag()
Observable.range(start: 1, count: 3)
    .scan(0) { $0 + $1 }
    .subscribe { print($0) }
    .addDisposableTo(disposeBag)

scan和swift的原生方法reduce很類似(區(qū)別在于scan后的Element數(shù)量和源Element數(shù)量一致活喊,但是reduce只會返回一個Element)丐膝,在Observable+Single中我們能夠找到它的定義:

public func scan<A>(seed: A, accumulator: (A, E) throws -> A) -> Observable<A> {
    return Scan(source: self.asObservable(), seed: seed, accumulator: accumulator)
}

seed的scan開始的初始值,accumulator的第一個參數(shù)為上一次操作的返回值,第二個參數(shù)為Observable隊列中的Element帅矗,然后返回處理結(jié)果偎肃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市浑此,隨后出現(xiàn)的幾起案子累颂,更是在濱河造成了極大的恐慌,老刑警劉巖凛俱,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊馏,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒲犬,警方通過查閱死者的電腦和手機朱监,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來原叮,“玉大人赫编,你說我怎么就攤上這事》芰ィ” “怎么了擂送?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長唯欣。 經(jīng)常有香客問我团甲,道長,這世上最難降的妖魔是什么黍聂? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任躺苦,我火速辦了婚禮,結(jié)果婚禮上产还,老公的妹妹穿的比我還像新娘匹厘。我一直安慰自己,他們只是感情好脐区,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布愈诚。 她就那樣靜靜地躺著,像睡著了一般牛隅。 火紅的嫁衣襯著肌膚如雪炕柔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天媒佣,我揣著相機與錄音匕累,去河邊找鬼。 笑死默伍,一個胖子當(dāng)著我的面吹牛欢嘿,可吹牛的內(nèi)容都是我干的衰琐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼炼蹦,長吁一口氣:“原來是場噩夢啊……” “哼羡宙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掐隐,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤狗热,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后虑省,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匿刮,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年慷妙,在試婚紗的時候發(fā)現(xiàn)自己被綠了僻焚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡膝擂,死狀恐怖虑啤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情架馋,我是刑警寧澤狞山,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站叉寂,受9級特大地震影響萍启,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜屏鳍,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一勘纯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钓瞭,春花似錦驳遵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸭丛,卻和暖如春竞穷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鳞溉。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工瘾带, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人穿挨。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓月弛,卻偏偏與公主長得像肴盏,于是被迫代替她去往敵國和親科盛。 傳聞我的和親對象是個殘疾皇子帽衙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 最近在學(xué)習(xí)RxSwift相關(guān)的內(nèi)容,在這里記錄一些基本的知識點贞绵,以便今后查閱厉萝。 Observable 在RxSwi...
    L_Zephyr閱讀 1,740評論 1 4
  • FRP是異步數(shù)據(jù)流編程 這不是什么新鮮的東西了。在前端編程中(用Javascript)榨崩,監(jiān)聽某個按鈕的點擊事件谴垫,并...
    superYang0033閱讀 2,098評論 1 8
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的母蛛,對什么是操作翩剪、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,841評論 0 10
  • 發(fā)現(xiàn) 關(guān)注 消息 RxSwift入坑解讀-你所需要知道的各種概念 沸沸騰關(guān)注 2016.11.27 19:11*字...
    楓葉1234閱讀 2,780評論 0 2
  • 《鄉(xiāng)士人物》前言和目錄 魯巴姓魯,叫什么名字彩郊,大伙并不清楚前弯,家里就父子倆,都是光棍秫逝,有人納悶恕出,是光棍怎么會有兒子?...
    亦農(nóng)閱讀 1,105評論 5 8