我在RxSwift中学习了示例代码。在文件GithubSignupViewModel1.swift中,validatedUsername的定义是:
t2
validateUsername方法最终被称为以下方法:
t1$x3 <- as.character(t1$x3)
t2$x3 <- as.character(t2$x3)
t1[t1$x1 %in% t2$x1 & as.character(t1$x2) %in% as.character(t2$x2), "x3"] <- t2$x3
> t1
# x1 x2 x3
#1 1 I a
#2 7 R a
#3 3 R a
#4 4 I b
#5 2 I b
#6 6 R b
这是我的困惑:
每当我在用户名文本字段中快速输入字符时,消息--------&gt; 1:,--------&gt; 2:显示,稍后消息--- -----&gt; 3:显示,但只显示了一个--------&gt; 3:消息。
当我输入较慢的字符时,消息--------&gt; 1:,--------&gt; 2:,--------&gt; 3:连续显示。
但是当我将flatMapLatest更改为flatMap时,我输入了多少个字符,我将得到相同数量的--------&gt; 3:message。
那么flatMapLatest如何在这里工作?
flatMapLatest如何过滤NSURLResponse的早期响应?
我读了一些关于flatMapLatest的内容,但没有一个能解释我的困惑。
我看到的是:
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)
将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)
}
更改为另一个变量时,变量(XX)不会影响a的订阅者。
但是let a = Variable(XX)
a.asObservable().flatMapLatest(...)
没有改变,它始终是a.value
!那么flatMapLatest如何工作?
答案 0 :(得分:16)
TheDroidsOnDroid的回答对我来说很清楚:
嗯,flatMap()得到一个值,然后执行长任务,然后执行 得到下一个值,前一个任务即使在新的时候仍然会完成 值到达当前任务的中间。这不是真的 我们需要因为当我们在搜索栏中获得新文本时,我们想要 取消上一个请求并启动另一个请求。那是什么 flatMapLatest()可以。
http://www.thedroidsonroids.com/blog/ios/rxswift-examples-3-networking/
您可以在Appstore上使用RxMarbles应用程序来使用运算符。
答案 1 :(得分:14)
目前尚不清楚你的困惑是什么。您是否在质疑flatMap
和flatMapLatest
之间的区别? flatMap
会映射到新的Observable
,如果需要再次flatMap
,它实际上会将两个映射的Observable
合并为一个。如果需要再次flatMap
,它将再次合并,等等。
使用flatMapLatest
时,如果映射了新的Observable
,则会覆盖最后一个Observable
(如果有)。没有合并。
编辑:
在回复您的评论时,您没有看到任何"------>3:"
打印件的原因是因为rx_request
Observable
在竞争之前已被处置,因为flatMapLatest
收到了新的元素,并映射到新的Observable
。处置后,rx_request
可能取消请求,并且不会在您打印的地方运行回调。旧的Observable
被处置掉了,因为当新的var list = ctx.Web.Lists.GetByTitle(listTitle);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
var result = ctx.LoadQuery(items.Where(i => (bool)i["IsSummary"]).Include(i => i["Name"], i => i["Start"], i => i["Finish"]));
ctx.ExecuteQuery();
foreach (var item in result)
{
Console.WriteLine(item["Name"]);
}
取代它时,它不再属于任何人。
答案 2 :(得分:9)
将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
使用flatMap
,我们得到
80
85
90
95
100
使用flatMapLatest
,我们得到
80
85
90
100
在此示例中,使用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并取消订阅前一个。
答案 3 :(得分:3)
我认为来自Ray Wenderlich tutorial的图表可以提供帮助。