如何在Angular 2中取消Promise.all()?

时间:2017-01-06 17:21:42

标签: javascript angular typescript promise

我目前有一个注册过程,每次下一次点击都会生成一个Promise.all(),它会调用很多http请求。如果客户端快速通过(非常快速地按下下一个按钮)所有的http请求都会累积起来并且它会弄乱我的应用程序。

有没有办法可以取消Promise.all(),这样如果他们点击下一步并且之前的Promise.all()仍在运行,我可以取消它吗?

3 个答案:

答案 0 :(得分:4)

您可以等待承诺完成,但您无法取消承诺。

您可以禁用以下下一个按钮,直到它们全部完成。

<button [disabled]="completed">Next</button>

答案 1 :(得分:0)

假设“取消Promise.all()”意味着“确保Promise.all()返回的承诺不遵循其成功路径”....

Promise不可取消,但可以使用基于模式的解决方案。

这里的概念相当简单。从本质上讲,在每一批承诺中,您都可以包含以下承诺:

    如果原始批次成功,
  • 将得到解决
  • 将在创建下一批时被拒绝。

这是一种善恶的种族。

困难的部分是使“超级聚合”对结果透明。

这是编写它的一种方式 - 也许不是最简洁 - 有人可能会找到更好的方法。

function BatchCanceller() {
    // Return a function, which accepts an array of promises and returns an aggregated promise.
    // Use the returned function like $q.all().
    var dfrd;
    return function(promises) {
        if(dfrd) {
            dfrd.reject(new Error('cancelled')); // reject previous batch
        }
        dfrd = $q.defer();
        // Preparation; ensure that `promises`, if all are successful, resolve `dfrd`.
        $q.all(promises).then(dfrd.resolve);
        // Now include `dfrd` in a super-aggregation of `promises`
        return $q.all(promises.concat(dfrd.promise)) // Will the aggregated `promises` resolve before another batch causes `dfrd.reject()`?
        .then(function(results) {
            // Yay! the aggregated `promises` won out.
            return results.splice(0, results.length-1); // remove the unwanted extra result.
        }); // no need to handle error here
    };
}

var batchCanceller = new BatchCanceller();

var promises = [/* whatever */];
batchCanceller(promises).then(function(results) {
    console.log(results);
}).catch(function(error) {
    console.log(error); // message is "cancelled" if another `batchCanceller(promises)` is executed before the previous one resolves.
});

在实践中,您可能会选择将BatchCanceller()表达为Angular工厂。

答案 2 :(得分:0)

我会使用observables,.center { margin: auto; width: 60%; border: 3px solid #73AD21; padding: 10px; } switchMap,类似

debounceTime

哪个基于https://angular.io/docs/ts/latest/tutorial/toh-pt6.html#!#-_observable-s

关于export class MyComponent implements OnInit { actions: Observable<any[]>; private signals = new Subject<string>(); constructor() {} submit(signal: string): void { this.signals.next(signal); } ngOnInit(): void { this.actions = this.signals .debounceTime(300) .distinctUntilChanged() .switchMap(signal => { // make http calls with the signal e.g // return this.service.getAction(signal) }) .catch(error => { // handle error }); } } 的一个好处是,如果另一个信号通过,它将取消任何飞行中的http请求。如果说你的服务器没有处理被取消的请求,那就没什么用了。