我如何有条件地发出两个可观察流?

时间:2017-07-20 08:14:42

标签: javascript rxjs reactive-programming rxjs5

我想知道任何方法都可以将一个流转换为另一个流。我已经有两个数字$和颜色$的流,他们输出数字和颜色,如[1,1,1,...]和['红色','红色','红色',...]。

我希望获得诸如[1,1,1,'红色','红色','红色','红色','红色','红色',1,1,1,...]等输出,此输出流将随机将数字$跳转到颜色$或反向。

我是RxJS的新手,并没有找到合适的方法来解决我的问题。所以我假设了一个方法jumpWhen(condition, streamJumpTo),一旦条件为真,处理流将被弃用,它将被转换为新流并开始工作。

let number$, color$

number$ = Rx.Observable.interval(300)
  .jumpWhen(Math.random() > 0.9, color$)
  .mapTo(1)

color$ = Rx.Observable.interval(500)
  .jumpWhen(Math.random() < 0.3, number$)
  .mapTo('red')

number$.subscribe(console.log)

问题是,如何使用Rx.js v5模拟此过程?注意:$ number和$ color可能会附加完全不同的运算符(不是简单的mapTo),所以我认为我们不应该尝试将两个流合并在一起。

关于此流的说明:

首先,每300毫秒输出1,有10%的机会(Math.random()> 0.9)将数字$切换为$ color。如果切换发生,流停止输出1,它开始每500毫秒输出red。总体输出似乎如下:

       1 - - 1 - - 'red' - - - - 'red' - - - - 'red' - - - - 1 - - 1 - ...
cond   f     f       t             f             f           t     f
time  300   600     900           1400         1900        2400   2700
rand  0.5   0.2     0.95          0.99          0.4        0.08   0.1

1 个答案:

答案 0 :(得分:0)

您可以使用Observable.if()

Observable.if(condition, thenSource, [elseSource])接受3个参数:

  1. 第一个参数接受一个返回布尔值的函数,
  2. 如果条件为真,则第二个参数是observable
  3. ,最后一个是else源数组,如果condition为false则发出。
  4. 由于您有两个可观察对象numbers$colors$,您可以编写条件函数并决定要发出哪些可观察对象。

    Observable.if(
        () => Math.random() > 0.5, //function that determines your condition
        number$, //this observable will be emitted if the above function returns true 
        color$ //this will be emitted if false
        )
    .subscribe(x => console.log(x));
    

    工作JSBin

    修改

    从评论中,我意识到我错误地理解了你的要求。对于您的情况,您可以使用.expand()运算符重复返回您选择的Observable,并相应地延迟:

    let test = Observable
    .of(1)
    .expand((prevData) => {
      let rand = Math.random();
      let number$ = Observable.of(1).delay(300);
      let color$ = Observable.of('red').delay(500);
    
      if (prevData === 1) {
        return rand > 0.9 ? color$ : number$;
      }
      else {
        return rand < 0.3 ? number$ : color$;
      }
    
    })
    .subscribe(x => console.log(x))
    

    编辑工作JSBin