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