RxJs - 具有间隔的最后一个请求

时间:2017-04-05 00:19:28

标签: javascript rxjs

我想知道如何在RxJS中获得类似下面的东西。

  1. 每隔一个请求将发送到服务器。
  2. 响应可能需要不同的时间。 (超过1s澄清)
  3. 但是当只有一些响应到达时,所有较旧的未完成请求都会被取消,订阅只会收到最新完成请求的结果。
  4. 看起来 switchMap 无法正常工作。因为每个下一个启动的请求在响应之前取消之前的请求。请参阅下面的代码。

    let counter = 0;
    let times = [1200, 500];
    
    let getSomePromise = function() {
      return new Promise((resolve) => {
        let i = counter;
        counter++;
        
        if (i < 2) {
          console.log('promise ' + i + ' start');
        }
        
        setTimeout(() => {
          if (i < 2) {    
            console.log('promise ' + i + ' finish');
            resolve(i);
          }
        }, times[i]);
      });
    }
    
    
    let ob = Rx.Observable.interval(1000)
      .switchMap(() => {
         return getSomePromise();
      });
    
    let sub = ob.subscribe((value) => {
      console.log('result ' + value);
    });
    <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>

    我明白了:

    promise 0 start
    promise 1 start
    promise 0 finish
    promise 1 finish
    result 1
    

    我想:

    promise 0 start
    promise 1 start
    promise 0 finish
    result 0
    promise 1 finish
    result 1
    

    谢谢。

2 个答案:

答案 0 :(得分:2)

您可以使用mergeMap()运算符来获得所需的结果。此运算符订阅从其投影函数返回的所有内部Observable,并重新发出所有项目。

但是,据我了解你的问题,你真的想要使用switchMap()(第3点确切地描述了switchMap的作用),但你的预期输出看起来像你想要{{1} }。

查看更新的代码及其输出:

&#13;
&#13;
mergeMap()
&#13;
let counter = 0;
let times = [1200, 500];

let getSomePromise = function() {
  return new Promise((resolve) => {
    let i = counter;
    counter++;
    
    if (i < 2) {
      console.log('promise ' + i + ' start');
    }
    
    setTimeout(() => {
      if (i < 2) {    
        console.log('promise ' + i + ' finish');
        resolve(i);
      }
    }, times[i]);
  });
}


let ob = Rx.Observable.interval(1000)
  .mergeMap(() => {
     return getSomePromise();
  });

let sub = ob.subscribe((value) => {
  console.log('result ' + value);
});
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您正在寻找.switchMap运营商。

Rx.Observable.interval(1000)
.switchMap(() => Rx.Observable.ajax(someUrl))
.subscribe(val => console.log(val));