2

遵循与问题 39 类似的示例:http: //reactivex.io/learnrx/

我正在尝试将方法调用search(query: String)转换为这些调用的序列。他们实现这一点的方法是创建一个,每次调用该方法时Variable我都会使用该值进行更新。querysearch(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"])with queryVariable.asObservable()。然后我将其映射到 Facebook 搜索(在 Facebook 上按姓名搜索人)。和subscribeNext我一起打印名字。如果我不使用takeUntil,它会按我的预期工作,我会得到 3 组结果,每个查询("A", "AB", "ABC")一组。

但是,如果我快速输入(在 Facebook 有时间响应请求之前),我只想要一个结果,用于 query "ABC"。这就是我添加takeUntil. 有了它,我希望facebookSearch(query: String)下一个调用会被忽略query,但是当前查询正在取消它,所以takeUntil我最终什么也没打印。

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

4

1 回答 1

3

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

1.使用flatMapLatest

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

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

2.使用share

为了使您的方法有效,您必须在将queryVariableObservable 用于以下情况时共享它的事件takeUntil

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

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

如果您不共享事件,则searchQuery.asObservable()intakeUntil创建自己的(重复)序列。然后,当在变量上设置新值时,searchQuery它会立即在 takeUntil() 序列中触发 Next 事件,并取消 facebookSearch 结果。

当您使用share()序列时,takeUntil将观察与其他序列相同的事件,在这种情况下,takeUntil序列会在 facebookSearch 返回响应后处理 Next 事件。

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

于 2016-04-10T20:56:43.100 回答