下面是与问题39类似的示例:http://reactivex.io/learnrx/
我正在尝试将方法调用search(query: String)
转换为这些调用的序列。我实现这一点的方法是创建一个Variable
,每次都用query
值更新调用CCD_ 4方法。
然后我的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"
,我的search(query: String)
方法将被"A"
、"AB"
和"ABC"
调用3次。这将被映射到具有CCD_ 12的CCD_。然后我把它映射到脸书搜索(在脸书上按名字搜索)。用subscribeNext
打印名字。如果我不使用takeUntil
,它会像我预期的那样工作,我会得到3组结果,每个查询一组("A"
、"AB"
、"ABC"
)。
但是,如果我快速键入(在Facebook有时间响应请求之前),我只想要一个查询"ABC"
的结果。这就是我添加takeUntil
的原因。有了它,我希望在下一个query
到来时忽略facebookSearch(query: String)
调用,但对于当前查询,它被取消了,所以有了这个takeUntil
,我最终什么都不打印。
这是一个已知的问题还是我做错了什么?
我使用了您的代码,找到了两个解决您问题的方案:
1.使用flatMapLatest
您可以只使用flatMapLatest
而不使用flatMap
和takeUntil
。flatMapLatest
只返回最新搜索请求的结果,并取消所有尚未返回的旧请求:
_ = queryVariable.asObservable()
.flatMapLatest { query -> Observable<String> in
return self.facebookSearch(query)
}
.subscribeNext {
print($0)
}
2.使用share
为了使您的方法发挥作用,您必须在将queryVariable
Observable用于takeUntil
:时共享它的事件
let queryObservable = queryVariable.asObservable().share()
_ = queryObservable
.flatMap { query -> Observable<String> in
return self.facebookSearch(query).takeUntil(queryObservable)
}
.subscribeNext {
print($0)
}
如果不共享事件,takeUntil
中的searchQuery.asObservable()
将创建自己的(重复的)序列。然后,当在searchQuery
变量上设置新值时,它会立即在takeUntil()序列中触发Next事件,并取消facebookSearch结果。
当您使用share()
时,takeUntil
中的序列正在观察与其他序列相同的事件,在这种情况下,takeUntil
序列在facebookSearch返回响应后处理Next事件。
IMHO第一种方式(flatMapLatest)是关于如何处理此场景的首选方式。