为什么在 rxswift 中连接 never()
why concat never() in rxswift
func signup(_ username: String, password: String) -> Observable<Bool> {
// this is also just a mock
let signupResult = arc4random() % 5 == 0 ? false : true
return Observable.just(signupResult)
.concat(Observable.never())
.throttle(0.4, scheduler: MainScheduler.instance)
.take(1)
}
我在 RxSwift 中看到一些代码,但我不明白为什么需要 concat(Observable.never())
这只是示例。 FUI,never
创建一个不发射任何项目且不终止的 Observable(来自 official documentation 的描述)
我自己也在理解这一点,所以请三思而后行:)
Observable.just
发出一次值并立即完成;几乎不需要任何时间;
.throttle(0.4, scheduler: MainScheduler.instance)
在序列中引入时间,用0.4s+确定值到return,
concat(Observable.never())
使输入序列变长 -运行 所以 throttle
首先有事情要做。
现在return Observable.just(signupResult)
就可以实现那个功能了。剩下的有什么用?
其他三个运算符导致延迟。由于连接的 Observable 是永无止境的,throttle
将等待至少 0.4 秒一次以确定为第一个节流 "chunk" 发出哪个值。 take(1)
然后在第一个值在 0.4 秒后发出后完成序列
对我来说,这似乎是实现延迟响应的一种非常费力的方法:)
@ctietze 的回答似乎是正确的。但是经过测试,我意识到 throttle
扼杀了整个概念。
基本上 throttle
将 return 观察开始后的值。这意味着它不会等到 0.4s
发出第一个值。
func testWithThrottle() -> Observable<Int> {
return
Observable.just(7) // 1
.concat(Observable.never()) // 2
.throttle(3.0, scheduler: Schedulers.background) // 3
.take(1) // 4
// 1. -7--|->
// 2. -7------------------------------->
// 3. -7------------------------------->
// 4. -7--|->
}
...
print("[\(Date())] Start!")
testWithThrottle().subscribe({ (event) in
print("[\(Date())] event: \(event)")
}).addDisposableTo(disposeBag)
print("[\(Date())] End!")
...
[2017-06-03 03:14:00 +0000] Start!
[2017-06-03 03:14:00 +0000] event: next(7)
[2017-06-03 03:14:00 +0000] event: completed
[2017-06-03 03:14:00 +0000] End!
那么,解决方案是什么?很简单,您需要改用 debounce
。
func testWithDebounce() -> Observable<String> {
return
Observable.of("A") // 1
.concat(Observable.never()) // 2
.debounce(3.0, scheduler: Schedulers.background) // 3
.take(1) // 4
// 1. -A-|->
// 2. -A------------------------------>
// 3. ---------------A---------------->
// 4. ---------------A-|->
}
...
[2017-06-03 03:24:21 +0000] Start Thrrotle!
[2017-06-03 03:24:21 +0000] Finish Thrrotle!
[2017-06-03 03:24:24 +0000] event: next(A)
[2017-06-03 03:24:24 +0000] event: completed
func signup(_ username: String, password: String) -> Observable<Bool> {
// this is also just a mock
let signupResult = arc4random() % 5 == 0 ? false : true
return Observable.just(signupResult)
.concat(Observable.never())
.throttle(0.4, scheduler: MainScheduler.instance)
.take(1)
}
我在 RxSwift 中看到一些代码,但我不明白为什么需要 concat(Observable.never())
这只是示例。 FUI,never
创建一个不发射任何项目且不终止的 Observable(来自 official documentation 的描述)
我自己也在理解这一点,所以请三思而后行:)
Observable.just
发出一次值并立即完成;几乎不需要任何时间;.throttle(0.4, scheduler: MainScheduler.instance)
在序列中引入时间,用0.4s+确定值到return,concat(Observable.never())
使输入序列变长 -运行 所以throttle
首先有事情要做。
现在return Observable.just(signupResult)
就可以实现那个功能了。剩下的有什么用?
其他三个运算符导致延迟。由于连接的 Observable 是永无止境的,throttle
将等待至少 0.4 秒一次以确定为第一个节流 "chunk" 发出哪个值。 take(1)
然后在第一个值在 0.4 秒后发出后完成序列
对我来说,这似乎是实现延迟响应的一种非常费力的方法:)
@ctietze 的回答似乎是正确的。但是经过测试,我意识到 throttle
扼杀了整个概念。
基本上 throttle
将 return 观察开始后的值。这意味着它不会等到 0.4s
发出第一个值。
func testWithThrottle() -> Observable<Int> {
return
Observable.just(7) // 1
.concat(Observable.never()) // 2
.throttle(3.0, scheduler: Schedulers.background) // 3
.take(1) // 4
// 1. -7--|->
// 2. -7------------------------------->
// 3. -7------------------------------->
// 4. -7--|->
}
...
print("[\(Date())] Start!")
testWithThrottle().subscribe({ (event) in
print("[\(Date())] event: \(event)")
}).addDisposableTo(disposeBag)
print("[\(Date())] End!")
...
[2017-06-03 03:14:00 +0000] Start!
[2017-06-03 03:14:00 +0000] event: next(7)
[2017-06-03 03:14:00 +0000] event: completed
[2017-06-03 03:14:00 +0000] End!
那么,解决方案是什么?很简单,您需要改用 debounce
。
func testWithDebounce() -> Observable<String> {
return
Observable.of("A") // 1
.concat(Observable.never()) // 2
.debounce(3.0, scheduler: Schedulers.background) // 3
.take(1) // 4
// 1. -A-|->
// 2. -A------------------------------>
// 3. ---------------A---------------->
// 4. ---------------A-|->
}
...
[2017-06-03 03:24:21 +0000] Start Thrrotle!
[2017-06-03 03:24:21 +0000] Finish Thrrotle!
[2017-06-03 03:24:24 +0000] event: next(A)
[2017-06-03 03:24:24 +0000] event: completed