do(onNext:) 和 subscribe(onNext:) 有啥区别?

Posted

技术标签:

【中文标题】do(onNext:) 和 subscribe(onNext:) 有啥区别?【英文标题】:what is difference between do(onNext:) and subscribe(onNext:)?do(onNext:) 和 subscribe(onNext:) 有什么区别? 【发布时间】:2018-12-31 10:55:14 【问题描述】:

我是 RxSwift 的新手,我不明白 do(onNext:)subscribe(onNext:) 之间的区别。

我用谷歌搜索,但没有找到很好的资源来解释差异。

【问题讨论】:

【参考方案1】:

在冷 Observable 链的开头有一个生成事件的函数,例如发起网络请求的函数。

除非订阅了 Observable,否则将调用该生成器函数(默认情况下,每次订阅 observable 时都会调用它。)因此,如果您将 do(onNext:) 添加到您的可观察链,不会调用该函数,也不会启动生成事件的操作。您必须添加 subscribe(onNext:) 才能实现。

(实际的内部结构比上面的描述要复杂一些,但对于这个解释来说已经足够接近了。)

【讨论】:

是的,你可以认为 subscribe 是针对主要效果,do 是针对其他副作用。 do 运算符在您的代码中应该很少见,而 subscribe 是必需的。 1) 我想如果你链接了do(onNext:)subscribe(onNext) 那么基本上它们都会触发,无论是什么,即会调用生成调用的函数,并且两个回调显然都会发生. 2)虽然这段代码编译.rx .notification(UIApplication.willEnterForegroundNotification) .toVoid() .do(onNext: resetRetries)你是说它永远不会触发?!因为没有订阅? 正确。 NotificationCenter.default.rx.notification(UIApplication.willEnterForegroundNotification).toVoid().do(onNext: resetRetries) 什么都不做。如果您查看notification(_:) 的实现,您会看到它创建了一个冷的observable,这意味着闭包传递给了observable,除非订阅了Observable,否则实际调用addObserver(forName:object:queue:) 的代码不会被调用。 【参考方案2】:

do 运算符允许您插入副作用;也就是说,处理程序做的事情不会以任何方式改变发出的事件。 do 只会将事件传递给链中的下一个运算符。

do操作符的使用方法在这里

您可以为任何或所有这些事件提供处理程序。

假设我们有一个从不发射任何东西的可观察对象。即使它什么也没发出,它仍然是一个可观察的,我们可以订阅它。 do 运算符允许我们在订阅时执行某事。 因此,当订阅该 observable 时,下面的示例将打印“Subscribed”。

如果您愿意,可以随意添加任何其他处理程序;它们就像 subscribe 的处理程序一样工作

let observable = Observable<Any>.never()
let disposeBag = DisposeBag()

  observable
    .do(onSubscribe: 
      print("Subscribed")
    )
    .subscribe(
      onNext:  element in
        print(element)
      ,
      onCompleted: 
        print("Completed")
      ,
      onDisposed: 
        print("Disposed")
      
    )
    .disposed(by: disposeBag)

【讨论】:

以上是关于do(onNext:) 和 subscribe(onNext:) 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift 调用 bind 立即触发 vs subscribe(onNext: )

Rx Swift 丢弃 .do(onNext: ) 我如何让它触发?

rxswift 绑定(onNext:VS 订阅(onNext:

捕获订阅 OnNext 操作可能引发的异常

RxJava Subscription 自动取消订阅

dispatch 和 _synchronized_subscribe RxSwift