这是我的代码的简短版本,将重现该问题:

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秒后触发通知。

最佳答案

为了回答我自己的问题,似乎delaySubscription仅适用于冷观测对象。

冷的可观察对象(例如timer)仅在已订阅时才开始触发通知,所有订阅它的人都会获得新的序列。这就是为什么简单地延迟对冷的可观察对象的订阅也会延迟所有通知的原因。

诸如UI事件之类的热可观察对象与其所有订阅者共享相同的序列,因此延迟订阅绝对不会对其通知产生影响。

相反,我可以使用flatMap运算符将每个源通知转换为另一个可观察到的对象,该对象在经过一定延迟后会触发其唯一的通知,并合并这些可观察对象的结果:

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)
    }
}

关于ios - delaySubscription不适用于rx_tap,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34529132/

10-14 23:20