取消一系列连续的异步请求



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

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

我有的例子是链接开关映射。新的点击将中止并重新启动第一个 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:我见过一些类似的问题,虽然它们看起来很具体,但我尽量通用。

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

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

最新更新