我目前有一个注册过程,每次下一次点击都会生成一个Promise.all(),它会调用很多http请求。如果客户端快速通过(非常快速地按下下一个按钮)所有的http请求都会累积起来并且它会弄乱我的应用程序。
有没有办法可以取消Promise.all(),这样如果他们点击下一步并且之前的Promise.all()仍在运行,我可以取消它吗?
答案 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请求。如果说你的服务器没有处理被取消的请求,那就没什么用了。