代码之家  ›  专栏  ›  技术社区  ›  Damn Vegetables

当N个事件中的任何一个发生时执行,但使用所有其他事件的最后结果

  •  0
  • Damn Vegetables  · 技术社区  · 6 年前

    假设有N个事件。当一个事件E发生时,如果E是N个事件中的一个事件,但仅在每个事件至少发生一次之后,我可以做些什么,并对每个事件使用最后的结果吗?

    我尝试了下面的代码,希望结果与注释中的一样

    val o1 = PublishSubject.create<String>();
    val o2 = PublishSubject.create<String>();
    val o3 = PublishSubject.create<String>();
    
    Observable.zip(o1,o2,o3,
            Function3<String, String, String, Array<String>> { t1, t2, t3 -> arrayOf(t1,t2,t3); })
            .observeOn(Schedulers.computation())
            .subscribe { t1 ->
                Log.d("so", "Result = " + t1.joinToString(" "));
            }
    
    o1?.onNext("homer"); //o2 and o3 have not been ready.
    Thread.sleep(1000);
    o1?.onNext("bart");  //o2 and o3 have not been ready.
    Thread.sleep(1000);
    o3?.onNext("doughnut"); //o2 has not been ready.
    Thread.sleep(1000);
    o2?.onNext("loves"); //at this point, print "Result = bart loves doughnut". 
                         //The last value of o1 is "bart",
                         //and the last value of o3 is "doughnut"
    Thread.sleep(1000);
    o1?.onNext("marge"); //marge loves doughnut
    Thread.sleep(1000);
    o2?.onNext("hates"); //marge hates doughnut
    Thread.sleep(1000);
    o3?.onNext("pie");   //marge hates pie
    Thread.sleep(1000);
    o3?.onNext("cake");  //marge hates cake
    Thread.sleep(1000);
    o2?.onNext("sees");  //marge sees cake
    Thread.sleep(1000);
    
    Log.d("so", "Done");
    

    但实际结果是

    Result = homer loves doughnut
    Result = bart hates pie
    Result = marge sees cake
    Done
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Michael Hoff    6 年前

    你的解决方案的问题是 zip ( docs )仅使用元素一次。如果将流[A1]和[B1、B2、B3]合并,则只会生成[(A1、B2)],然后等待下一个A,即使下一个B已经可用。

    但是,操作员 combineLatest ( docs )可以实现所需的行为:

    Observable.combineLatest(o1, o2, o3, Function3<String, String, String, String> {
        t1, t2, t3 -> arrayOf(t1, t2, t3).joinToString(" ")
    }).subscribe {
        println(it)
    }
    

    输出:

    bart loves doughnut
    marge loves doughnut
    marge hates doughnut
    marge hates pie
    marge hates cake
    marge sees cake
    Done
    

    一般建议:退房 全部的 这个 available operators 在ReactiveX中。图形文档非常直观。最后,这些是您想要的基本构建块 充分地 理解以实现更复杂的行为。