RXSwift-take直到下一次活动前取消



下面是与问题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而不使用flatMaptakeUntilflatMapLatest只返回最新搜索请求的结果,并取消所有尚未返回的旧请求:

_ = 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)
    }

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

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

IMHO第一种方式(flatMapLatest)是关于如何处理此场景的首选方式。

最新更新