2016-04-10 73 views
1

取消按照類似的例子在這裏提問39:http://reactivex.io/learnrx/RXSwift - takeUntil前一個事件

我試圖改變一個方法調用到這些調用序列。 他們這樣做我是通過創建一個Variable我更新query值每次 方法被調用。

然後,我有這在我的init()

_ = queryVariable.asObservable().flatMap({ query -> Observable<[JSON]> in 
    return self.facebookSearch(query).takeUntil(self.queryVariable.asObservable()) 
}).subscribeNext({ result in 
    if let name = result[0]["name"].string { 
     print(name) 
    } else { 
     print("problem") 
    } 
}) 

如果鍵入"ABC",我方法將"A""AB""ABC"被稱爲3倍。 這將映射到seq(["A", "AB", "ABC"])queryVariable.asObservable()。 然後我將它映射到Facebook搜索(通過他們在Facebook上搜索人名)。 並與subscribeNext我打印名稱。 如果我不使用takeUntil,它可以像我期望的那樣工作,我會得到3組結果,每個查詢一個("A","AB","ABC")。

但是,如果我輸入快速(在Facebook有時間響應請求之前),我只想要一個結果,查詢"ABC"。這就是爲什麼我添加了takeUntil。有了它,我預計在下一個query進來時,facebookSearch(query: String)調用被忽略,但它被取消當前查詢,所以這takeUntil我最終打印什麼都沒有。

這是一個已知問題還是我做錯了什麼?

回答

2

我用你的代碼,並發現了兩個解決方案,您的問題:

1.使用flatMapLatest

您可以只使用flatMapLatest代替flatMaptakeUntilflatMapLatest只返回了最新的搜索請求的結果,並取消尚未退還所有舊請求:

_ = queryVariable.asObservable() 
    .flatMapLatest { query -> Observable<String> in 
     return self.facebookSearch(query) 
    } 
    .subscribeNext { 
     print($0) 
    } 

2.使用share

爲了讓你的方法工作,你必須分享的活動您queryVariable可觀察的時候,你還可以使用它爲takeUntil

let queryObservable = queryVariable.asObservable().share() 

_ = queryObservable 
    .flatMap { query -> Observable<String> in 
     return self.facebookSearch(query).takeUntil(queryObservable) 
    } 
    .subscribeNext { 
     print($0) 
    } 

如果您不同意的事件中,searchQuery.asObservable()takeUntil中創建了自己的(重複)序列。然後,在searchQuery變量上設置新值時,它立即在takeUntil()序列中觸發Next事件,並取消facebookSearch結果。

當您使用share()序列中takeUntil是觀察同一事件的其他序列,並在這種情況下,takeUntil序列處理facebookSearch返回的響應之後的下一個事件。

恕我直言第一種方式(flatMapLatest)是如何處理這種情況的首選方式。

+0

但我沒有取消整個序列,我只在特定的facebookSearch上使用了takeUntil。就像練習39一樣。這裏有什麼不同? –

+0

此外,如果不是變量,我使用PublishSubject ,takeUntil按照我所述的方式工作。但我真的不明白其中的差別。 –

+0

好的,我看了一下示例39.我將在示例和代碼之間添加區別到答案。 – joern