理解monix中的观察者

时间:2018-05-23 11:34:41

标签: scala functional-programming monix

我正在阅读有关观察员广告的Monix documentation广告,我面对以下示例:

  

或者您可以快速构建仅记录事件的Observer   收到。我们将在其他样本中使用它:

import monix.reactive.Observer

val out = Observer.dump("O")
// out: Observer.Sync[Any]

out.onNext(1)
//=> 0: O-->1
// res0: Ack = Continue

out.onNext(2)
//=> 1: O-->2
// res0: Ack = Continue

out.onComplete()
//=> 2: O completed

然而,下一个ILLEGAL例子:

  

喂养两个元素,然后停止。这不合法:

// BAD SAMPLE
observer.onNext(1)
observer.onNext(2)
observer.onComplete()

所以我们可以看到相同的onNext -> onNext -> onComplete链。这不合法吗?为什么呢?

1 个答案:

答案 0 :(得分:1)

在您链接的文档中,直接在示例

之后进行了解释

这是合法的方式:

observer.onNext(1).map {
  case Continue =>
    // We have permission to continue
    observer.onNext(2)
    // No back-pressure required here
    observer.onComplete()
    Stop
  case Stop =>
    // Nothing else to do
    Stop
}

正如您在评论中看到的那样,问题是背压。那么为什么有一个例子,使用.dump似乎是非法的?

请注意该示例中的注释:

//=> 0: O-->1
// res0: Ack = Continue

这些评论显示了在Scala REPL中运行它时会得到什么。当您输入表达式并点击返回时,REPL会输出类似res0的内容,并让您知道最后一个命令的返回值是什么。

所以这个例子展示了:

  • 从REPL提供观察员
  • 每个.onNext已完成Continue

编写以这种方式提供观察者的程序是不正确的,但这是正确的转录法律执行给观察者。

您可以在Contract section

下查看与背压有关的规则
  
      
  1. 背压:每次onNext调用必须等待上一次onNext调用的Future [Ack]返回的Continue结果。
  2.   
  3. onComplete和onError的背压是可选的:当调用onComplete或onError时,不需要等待前一个onNext的Future [Ack]。
  4.   

这是一个很好的观点,因为优雅的背压管理是反应流的重要承诺之一。