lei*_*701 12 functional-programming reactive-cocoa swift rx-swift
我在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)
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
这是我的困惑:
每当我在用户名文本字段中快速输入一个字符时,消息--------> 1:,--------> 2:显示,以及稍后的消息-------- > 3:显示,但只显示一个--------> 3:消息.
当我输入较慢的字符时,消息--------> 1:,--------> 2:,--------> 3:连续显示.
但是当我将flatMapLatest更改为flatMap时,我输入了多少个字符,我将得到相同数量的--------> 3:message.
那么flatMapLatest如何在这里工作?
flatMapLatest如何过滤NSURLResponse的早期响应?
我读了一些关于flatMapLatest的内容,但没有一个能解释我的困惑.
我看到的是:
let a = Variable(XX)
a.asObservable().flatMapLatest(...)
Run Code Online (Sandbox Code Playgroud)
当更改a.value为另一个变量时,变量(XX)不会影响a的用户.
但是input.username没有改变,它总是一个testfield.rx_text!那么flatMapLatest如何工作呢?
小智 16
TheDroidsOnDroid的回答对我来说很清楚:
好吧,flatMap()获取一个值,然后执行长任务,当它获得下一个值时,即使新值到达当前任务的中间,前一个任务仍将完成.这不是我们真正需要的,因为当我们在搜索栏中获得新文本时,我们想要取消之前的请求并启动另一个请求.这就是flatMapLatest()的作用.
http://www.thedroidsonroids.com/blog/ios/rxswift-examples-3-networking/
您可以在Appstore上使用RxMarbles应用程序来操作运算符.
sol*_*ell 14
目前尚不清楚你的困惑是什么.你质疑之间的区别flatMap和flatMapLatest? flatMap将映射到一个新的Observable,如果它需要flatMap再次,它实质上将两个映射的Observables 合并为一个.如果它需要flatMap再次,它将再次合并,等.
使用flatMapLatest,当Observable映射一个new时,Observable如果有一个,则覆盖最后一个.没有合并.
编辑:回应你的评论,你没有看到任何"------>3:"打印的原因是因为那些rx_request Observables在他们可以竞争之前被处置,因为flatMapLatest收到了一个新元素,并且这映射到一个新的Observable.处置后,rx_request可能会取消请求,并且不会在您打印的地方运行回调.旧Observable的处置因为当新的取代它时它不再属于任何人.
将Observable序列发出的元素转换为Observable序列,并将来自Observable序列的发射合并为单个Observable序列.例如,当您有一个Observable序列本身发出Observable序列,并且您希望能够对来自Observable序列的新发射作出反应时,这也很有用.flatMap和flatMapLatest之间的区别在于,flatMapLatest只会从最近的内部Observable序列中发出元素.
let disposeBag = DisposeBag()
struct Player {
var score: Variable<Int>
}
let = Player(score: Variable(80))
let = Player(score: Variable(90))
let player = Variable()
player.asObservable()
.flatMap { $0.score.asObservable() } // Change flatMap to flatMapLatest and observe change in printed output
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
.score.value = 85
player.value =
.score.value = 95 // Will be printed when using flatMap, but will not be printed when using flatMapLatest
.score.value = 100
Run Code Online (Sandbox Code Playgroud)
有了flatMap,我们得到
80
85
90
95
100
Run Code Online (Sandbox Code Playgroud)
有了flatMapLatest,我们得到
80
85
90
100
Run Code Online (Sandbox Code Playgroud)
在此示例中,使用flatMap可能会产生意想不到的后果.在分配给player.value之后,.score将开始发出元素,但之前的内部Observable序列(.score)仍然会发出元素.通过将flatMap更改为flatMapLatest,只有最新的内部Observable序列(.score)才会发出元素,即将.score.value设置为95无效.
flatMapLatest实际上是map和switchLatest运算符的组合.
另外,我发现https://www.raywenderlich.com/158205/rxswift-transforming-operators这个很有用
flatMap
跟上它创建的每个可观察对象,每个元素添加到源可观察对象上
flatMapLatest
使flatMap最不同的是它将自动切换到最新的observable并取消订阅前一个.
| 归档时间: |
|
| 查看次数: |
10273 次 |
| 最近记录: |