我在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如何工作? 最佳答案
目前尚不清楚您的困惑是什么。您是否质疑flatMap
和flatMapLatest
之间的区别? flatMap
将映射到一个新的Observable
,如果需要再次使用flatMap
,它将本质上将两个映射的Observable
合并为一个。如果需要再次flatMap
,它将再次合并,依此类推。
使用flatMapLatest
,当映射了一个新的Observable
时,如果存在,它将覆盖最后一个Observable
。没有合并。
编辑:
根据您的评论,您看不到任何"------>3:"
打印的原因是因为那些rx_request
Observable
s在竞争之前就已被处理掉了,因为flatMapLatest
收到了一个新元素,并且映射到了新的Observable
。处理后,rx_request
可能会取消请求,并且不会在您正在打印的地方运行回调。废弃旧的Observable
是因为当新的ojit_code取代它时,它不再属于任何人。