ios - RXSwift - takeUntil 在下一个事件之前取消

标签 ios swift facebook rx-swift reactivex

这里采用与问题 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”。 它将通过 queryVariable.asObservable() 映射到 seq(["A", "AB", "ABC"])。 然后我将其映射到 Facebook 搜索(在 Facebook 上按姓名搜索人员)。 然后使用 subscribeNext 打印名称。 如果我不使用 takeUntil,它会按我的预期工作,我会得到 3 组结果,每个查询对应一组结果("A", “AB”“ABC”)。

但是,如果我输入速度很快(在 Facebook 有时间响应请求之前),我只需要一个结果,即查询“ABC”。这就是我添加 takeUntil 的原因。有了它,我希望在下一个查询到来时忽略 facebookSearch(query: String) 调用,但当前查询将被取消,因此这个 takeUntil 我最终没有打印任何内容。

这是一个已知问题还是我做错了什么?

最佳答案

我使用了您的代码并找到了解决您问题的两种解决方案:

<强>1。使用flatMapLatest

您可以只使用 flatMapLatest 而不是 flatMaptakeUntilflatMapLatest 仅返回最新搜索请求的结果,并取消所有尚未返回的旧请求:

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

<强>2。使用分享

为了使您的方法发挥作用,当您将 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 事件。

恕我直言,第一种方法(flatMapLatest)是处理这种情况的首选方法。

关于ios - RXSwift - takeUntil 在下一个事件之前取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36534964/

相关文章:

ios - 快速使用耳机

ios - Vfr Reader从右到左阅读

ios - 用过渡呈现 viewController

android - 如果在模拟器上安装了 Facebook 应用程序,则无法登录到 Facebook - Android 4.3

javascript - 如何检查用户是否已经登录facebook?

ios - 进程间 SQLite 线程安全(在 iOS 上)

ios - ADAL iOS 静默登录抛出错误

swift - 在 Swift 中将数组传递给具有可变数量参数的函数

ios - 类型 'Int' 的值永远不能为 nil,swift 2.2 中不允许比较

node.js - 等待 Facebook Messenger 机器人的短信回复