这是我的代码的简短版本,它将重现问题:
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let source = button.rx_tap.map { _ in "source" }
let delay = source.map { _ in "delayed" }
.delaySubscription(2.0, MainScheduler.sharedInstance)
[source, delay].toObservable().merge()
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
}
}
我希望点击按钮后“延迟”信号点亮2秒,但没有这样的运气。实际发生的事情:我第一次点击按钮时,“来源”会发射,但没有其他事情发生。然后,当我再次点击时,“源”和“延迟”同时点火。我认为这是一些线程问题,所以我尝试在任何地方添加observeOn(MainScheduler.sharedInstance)
,但它没有帮助。有什么想法吗?
更新:通过向流添加.debug()
,我发现延迟的流实际上在2秒后订阅了源。但这仍然无法解释为什么它也不会在2秒后发出通知。
答案 0 :(得分:2)
要回答我自己的问题,似乎delaySubscription
仅适用于冷可观测量。
冷可观察对象,例如timer
,只有在订阅时才开始触发通知,并且订阅它的每个人都会得到一个新的序列。这就是为什么简单地延迟冷观察的订阅也会延迟所有通知。
热门观察,例如UI事件,与所有订阅者共享相同的序列,因此延迟订阅绝对不会影响其通知。
相反,我可以使用flatMap
运算符将每个源通知转换为另一个在一定延迟后触发其唯一通知的observable,并合并这些observable的结果:
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
let source = button.rx_tap.map { _ in "source" }
let delayed = source.flatMap { _ in
timer(1.0, MainScheduler.sharedInstance)
.map { _ in "delayed" }
}
[source, delayed]
.toObservable().merge()
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
}
}