取消一系列连续的非同步请求

时间:2018-06-29 21:58:01

标签: rxjs

假设用户输入触发了一个http请求A,结果为A,则应用程序必须发出另一个请求B并显示最终结果。

如果收到新的用户输入,则应取消所有http请求。

我的示例是链接switchMaps。新的点击将中止并重新启动第一个switchMap请求。第一个switchMap的新输出将取消并重新启动第二个。但是,单击不会重新启动第二个switchMap。

我很高兴提出有关如何重新考虑这一问题的建议。取消请求是目标,过滤/忽略结果是作弊:)。

http://jsbin.com/roranoh/4/edit?js,console

function obFc(name) {
  return {
    next: function (x) { console.log(name+ ' - ' + x)  },
    error: function (err) { console.log(name +' error ' + err) },
    complete: function () { console.log(name +' done') },
  }
};

function simulateHttp(val: any, delay:number) {
    return Rx.Observable.of(val).delay(delay);
}

click1$ = Rx.Observable.of('1').delay(1000);
click2$ = Rx.Observable.of('2').delay(4000);

click$ = Rx.Observable.merge( click1$, click2$ );
click$.subscribe( obFc('Click') );

click$
  .switchMap( (val) => {
    console.log('Fetching data A' + val);
    return simulateHttp(val + " A", 2000);
  })
  .do((v)=> console.log('received:' + v))
  .switchMap( val => {
    console.log('Fetching data B')
    return simulateHttp( val + " B", 2000);
  })
  .subscribe( obFc('Finished ') );

PS:我看过一些类似的问题,尽管它们看起来很具体,但我尝试了尽可能通用。

1 个答案:

答案 0 :(得分:1)

只需移动第二个switchMap,使其直接链接到第一个simulateHttp内的switchMap

click$
  .switchMap( (val) => {
    console.log('Fetching data A' + val);
    return simulateHttp(val + " A", 2000)
      .do((v)=> console.log('received:' + v))
      .switchMap(val => {
        console.log('Fetching data B')
        return simulateHttp(val + " B", 2000);
      });
  })
  .subscribe(obFc('Finished'));

然后,当再次单击时,外部switchMap中组成的整个链将被取消订阅。

此外,内部的switchMap将不再需要切换-因为HTTP的可观察对象仅发出一次-因此可以使用mergeMap代替。