代码之家  ›  专栏  ›  技术社区  ›  N A

Monix:InputStreamObservable不支持多个订阅者

  •  4
  • N A  · 技术社区  · 8 年前

    我试图将(String,Date)的一个可观察对象拆分为两个不同的可观察对象,并将它们压缩在一起,如下所示

    import monix.execution.Scheduler.Implicits.global
    val x = Observable.fromIterator((0 to 10).map(i => (s"a $i", s"b $i")).toIterator)
    
    val y = Observable.toReactive(x)
    
    val fileStream = Observable.fromReactivePublisher(y).mapAsync(5)(a => Task{println(a._1); a._1})
    val dateStream = Observable.fromReactivePublisher(y).mapAsync(5)(a => Task{println(a._2); a._2})
    
    fileStream.zip(dateStream)
      .map(println)
      .subscribe()
    

    但我有以下例外

    monix.reactive.exceptions.MultipleSubscribersException: InputStreamObservable does not support multiple subscribers
        at monix.reactive.exceptions.MultipleSubscribersException$.build(MultipleSubscribersException.scala:51)
        at monix.reactive.internal.builders.IteratorAsObservable.unsafeSubscribeFn(IteratorAsObservable.scala:42)
        at monix.reactive.Observable$$anon$6.subscribe(Observable.scala:155)
        at monix.reactive.internal.builders.ReactiveObservable.unsafeSubscribeFn(ReactiveObservable.scala:38)
        at monix.reactive.internal.operators.MapAsyncParallelObservable.unsafeSubscribeFn(MapAsyncParallelObservable.scala:60)
        at monix.reactive.internal.builders.Zip2Observable.unsafeSubscribeFn(Zip2Observable.scala:158)
        at monix.reactive.Observable$$anon$5.unsafeSubscribeFn(Observable.scala:139)
        at monix.reactive.Observable$class.subscribe(Observable.scala:71)
        at monix.reactive.Observable$$anon$5.subscribe(Observable.scala:136)
        at monix.reactive.Observable$class.subscribe(Observable.scala:90)
        at monix.reactive.Observable$$anon$5.subscribe(Observable.scala:136)
        at monix.reactive.Observable$class.subscribe(Observable.scala:120)
        at monix.reactive.Observable$$anon$5.subscribe(Observable.scala:136)
        at monix.reactive.Observable$class.subscribe(Observable.scala:112)
        at monix.reactive.Observable$$anon$5.subscribe(Observable.scala:136)
    
    2 回复  |  直到 8 年前
        1
  •  2
  •   Sergei Shubin    8 年前

    是否强制转换为/从被动?

    解决这个问题的一个方法是 val x = Observable.fromIterable((0 to 10).map(i => (s"a $i", s"b $i"))) ,但对于无限个流,它将超出内存错误。

    另一种方法是使用 .multicast(Pipe.publish[]) 然后 obs.connect() 记录代码:

    import monix.execution.Scheduler.Implicits.global
    val x = Observable.fromIterator((0 to 10).map(i => (s"a $i", s"b $i")).iterator)
    
    val y = Observable.toReactive(x)
    val obsY = Observable.fromReactivePublisher(y)
    val connectY = obsY.multicast(Pipe.publish[(String, String)])
    
    val fileStream = connectY.mapAsync(5)(a => Task{println(a._1); a._1})
    val dateStream = connectY.mapAsync(5)(a => Task{println(a._2); a._2})
    
    fileStream.zip(dateStream)
      .map(println)
      .subscribe()
    
    connectY.connect()
    
    Thread.sleep(5000)
    
        2
  •  0
  •   Klugscheißer    7 年前

    除了sergei shubin的回答之外,还可以暂时改变 Observable 进入“热”可观察状态,可使用 publishSelector 无需手动处理 multicast . 这看起来像:

    val x = Observable.fromIterator((0 to 10).map(i => (s"a $i", s"b $i")).toIterator)
    
    val zipped = x.publishSelector { o =>
      val fileStream = o.mapParallelUnordered(5)(a => Task{println(a._1); a._1})
      val dateStream = o.mapParallelUnordered(5)(a => Task{println(a._2); a._2})
    
      fileStream.zip(dateStream)
    }
    
    zipped
      .map(println)
      .subscribe()
    
    推荐文章