我在RxSwift中学习了示例代码。在文件GithubSignupViewModel1.swift中,validatedUsername的定义为:

validatedUsername = input.username //the username is a textfiled.rx_text
    .flatMapLatest { username -> Observable<ValidationResult> in
        print("-------->1:")
        return validationService.validateUsername(username)
            .observeOn(MainScheduler.instance)
            .catchErrorJustReturn(.Failed(message: "Error contacting server"))
    }
    .shareReplay(1)

validateUsername方法最终称为以下方法:
func usernameAvailable(username: String) -> Observable<Bool> {
    // this is ofc just mock, but good enough
    print("-------->2:")
    let URL = NSURL(string: "https://github.com/\(username.URLEscaped)")!
    let request = NSURLRequest(URL: URL)
    return self.URLSession.rx_response(request)
        .map { (maybeData, response) in
            print("-------->3:")
            return response.statusCode == 404
        }
        .catchErrorJustReturn(false)
}

这是我的困惑:

每当我在用户名文本字段中快速输入字符时,都会显示消息--------> 1 :、 --------> 2:和稍后的消息-------- > 3:显示,但仅显示一个--------> 3:消息。

当我输入较慢的字符时,依次显示消息--------> 1 :、 --------> 2 :、 --------> 3:。

但是,当我将flatMapLatest更改为flatMap时,输入了多少个字符,我将得到相同数量的--------> 3:消息。

那么flatMapLatest在这里如何工作?

flatMapLatest如何过滤来自NSURLResponse的早期响应?

我阅读了一些有关flatMapLatest的内容,但是没有一个可以解释我的困惑。

我看到的是这样的:
let a = Variable(XX)
a.asObservable().flatMapLatest(...)

当将a.value更改为另一个变量时,变量(XX)将不会影响a的订阅者。

但是input.username不变,它始终是testfield.rx_text!那么flatMapLatest如何工作?

最佳答案

目前尚不清楚您的困惑是什么。您是否质疑flatMapflatMapLatest之间的区别? flatMap将映射到一个新的Observable,如果需要再次使用flatMap,它将本质上将两个映射的Observable合并为一个。如果需要再次flatMap,它将再次合并,依此类推。

使用flatMapLatest,当映射了一个新的Observable时,如果存在,它将覆盖最后一个Observable。没有合并。

编辑:
根据您的评论,您看不到任何"------>3:"打印的原因是因为那些rx_request Observable s在竞争之前就已被处理掉了,因为flatMapLatest收到了一个新元素,并且映射到了新的Observable。处理后,rx_request可能会取消请求,并且不会在您正在打印的地方运行回调。废弃旧的Observable是因为当新的ojit_code取代它时,它不再属于任何人。

10-06 05:20