RXJS:如何以随机间隔(在指定范围内)生成数字流?

时间:2016-01-28 11:47:36

标签: javascript rxjs

我想使用RXJS来设置一个ORDERED数据流,该数据流以随机间隔(比如每1-5秒)发出一个数字,我想用它作为时间随机数据源来测试RXJS的其他部分。以下代码以随机顺序生成项目(由于延迟)但我希望订单仅保留随机时间。

function randomDelay(bottom, top) {
  return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
}

var source = Rx.Observable
  .range(1, 10)
  .flatMap(function (x) {
    return Rx.Observable
      .of(x)
      .delay(randomDelay(1000,5000));
  })
 .timeInterval();

var subscription = source.subscribe(
  function (x) {
     $("#result").append('Next: ' +  JSON.stringify(x) +  '<br>');
  },
  function (err) {
     $("#result").append('Error: ' + err);
  },
  function () {
     $("#result").append('Completed');
  });

给出了以下输出的变体:

Next: {"value":1,"interval":1229}
Next: {"value":2,"interval":321}
Next: {"value":4,"interval":645}
Next: {"value":5,"interval":28}
Next: {"value":9,"interval":728}
Next: {"value":10,"interval":269}
Next: {"value":3,"interval":107}
Next: {"value":6,"interval":265}
Next: {"value":8,"interval":1038}
Next: {"value":7,"interval":199}

3 个答案:

答案 0 :(得分:4)

使用concatMap代替flatMap

此处的文档: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/concatmap.md

var source = Rx.Observable
  .range(1, 10)
  .concatMap(function (x) {
    return Rx.Observable
      .of(x)
      .delay(randomDelay(1000,5000));
  })
 .timeInterval();

答案 1 :(得分:1)

我只是将此问题作为另一个问题的基础,如果有人感兴趣,则必须将其更新为RxJs 6。

const { range, of } = rxjs;
const { concatMap, delay } = rxjs.operators;

range(1, 10).pipe(
  concatMap(i => of(i).pipe(delay(1000 + (Math.random() * 4000))))
).subscribe(val => { console.log(val); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>

答案 2 :(得分:0)

我建议将这个问题分为两个子问题:i)以随机间隔发射; ii)产生随机值。第一个问题可以通过合适的自定义RxJS观察器解决(这就是crazyObservable的作用);第二个问题可以通过对crazyObservable的自定义订阅来解决。

crazyObservable具有三个参数:totalNumberOfEmissions,timeInterval和totalNumberOfTimeIntervals;它返回一个自定义的可观察对象,该对象在totalNumberOfTimeIntervals范围内随机发出totalNumberOfEmissions。

要获得所需的行为,请随意设置totalNumberOfEmissions,timeInterval和totalNumberOfTimeIntervals。这个Marble diagram会有所帮助。

var oneHourRandomTenHundredRequisitions$ = crazyObservable(1000,1000,60*60);

let testComponent1 = oneHourRandomTenHundredRequisitions$.subscribe({
next() { <a call to your random generator> } ,
error() { <your custom error call> },
complete() { <your custom complete call> }
});