如何在rxjs中获得限制值?

时间:2017-05-16 02:16:28

标签: javascript rxjs reactive-programming throttling

来自rxjs网站节流示例,

发射的序列是0 4 2 1 3。

输出序列为0 1.(因为丢弃了4,2和1)

var Rx = require('rxjs/Rx');
var times = [
  { value: 0, time: 100 },
  { value: 1, time: 600 },
  { value: 2, time: 400 },
  { value: 3, time: 900 },
  { value: 4, time: 200 }
];

// Delay each item by time and project value;
var source = Rx.Observable.from(times)
  .flatMap(function (item) {
    return Rx.Observable
      .of(item.value)
      .delay(item.time);
  })
  .throttleTime(300 /* ms */);

var subscription = source.subscribe(
  function (x) {
    console.log('Next: %s', x);
  },
  function (err) {
    console.log('Error: %s', err);
  },
  function () {
    console.log('Completed');
  });

控制台将输出

Next: 0 (at 100ms) // The value 4 was dropped(at 200ms)
                   // The value 2 was dropped(at 400ms)
Next: 1 (at 600ms)
                   // The value 3 was dropped(at 900ms)
Completed

但是,是否有可能获得丢弃的值流?

Next: 4 (at 200ms)
Next: 2 (at 400ms)
Next: 3 (at 900ms)
Completed

1 个答案:

答案 0 :(得分:1)

  1. 将索引附加到来源。
  2. 合并源的最新索引值和限制。
  3. 比较源和节流的索引。如果源索引>受限制的索引然后源不受限制。
  4. 删除已获得的索引。
  5. 您可以在另一种情况下使用此技术。

    var Rx = require('rxjs/Rx');
    var times = [
        { value: 0, time: 100 },
        { value: 1, time: 600 },
        { value: 2, time: 400 },
        { value: 3, time: 900 },
        { value: 4, time: 200 }
    ];
    
    // Delay each item by time and project value;
    var source = Rx.Observable.from(times)
        .mergeMap(function (item) {
            return Rx.Observable
                .of(item.value)
                .delay(item.time);
        });
    
    var indexedSource = source
        .scan((_, value, index) => {
            // console.log(`value = ${value}, index = ${index}`)
            return [value, index];
        }, undefined)
        .share();
    
    var indexedThrottled = indexedSource
        .throttleTime(300 /* ms */);
    
    var throttled = indexedThrottled
        .map(value => value[0]);
    
    var notThrottled = Rx.Observable.combineLatest(indexedThrottled, indexedSource)
        .filter(combined => {
            var filteredIndex = combined[0][1];
            var sourceIndex = combined[1][1];
    
            return sourceIndex > filteredIndex ? true : false;
        })
        .map(combined => {
            return combined[1][0];
        });
    
    source.subscribe(value => console.log(`source : ${value}`));
    throttled.subscribe(value => console.log(`++++++ : ${value}`));
    notThrottled.subscribe(value => console.log(`------ : ${value}`));