我有一个异步行为的保存功能,因此我使用的是promises。主要保存事件将进入并且只有一次{...}}和then
处理程序附加到它们。对于我的代码示例,这将在catch
方法中发生。现在可能会有以后调用的任意数量的其他保存调用,您可以参考importantSave
方法。
有没有办法让sideSave
方法中的then
和catch
处理程序在调用之前等待所有的侧面保存解析/拒绝,即使它们是先建立?
例如,我有以下代码:
importantSave
有没有办法改变这一点,以便在sideSave调用中任何class Adapter {
promise;
next_attempt;
attempt() {
if ( this.promise && this.promise.isPending() ) {
this.next_attempt = this.attempt.bind( this );
return this.promise.then( ()=> {
if ( this.next_attempt ) {
return this.next_attempt();
}
} );
} else {
this.promise = new Promise( resolve=> {
setTimeout( resolve, 3000 );
} );
return this.promise;
}
}
}
const adapter = new Adapter();
function importantSave() {
adapter.attempt()
.then( ()=> {
console.log( 'Hello from the important save!' );
} );
}
function sideSave() {
adapter.attempt()
.then( ()=> {
console.log( 'Hello from the side save!' );
} );
}
// the important save which sets up its then and catches, but wants to be called after all have finished
importantSave();
// any number of side saves, but will only be called with the last side save
sideSave();
sideSave();
sideSave();
之后实际运行importantSave中的then
?我的真实世界示例将在每次调用之间延迟调用保存功能3次,并且只有在所有3次失败时才会拒绝。如果在所有3次失败之前发生另一次保存调用,我希望最新的调用是“next_attempt”,覆盖任何其他尝试保存,而第一次仍未决。如果原始调用未能保存,但是其中一个“sideSave”调用已通过,我希望thens
完成,从而落入当时,而不是原始调用失败的捕获。
答案 0 :(得分:1)
通常这样做的方式是使用Promise.all
。
添加您需要在数组中解析的所有promise并将其作为参数传递:
Promise.all([importantSave(), sideSave(), sideSave(), sideSave()]).then(_ => {
console.log('all done');
});
您当然可以动态构建数组:
var arr = [importantSave()];
arr.push(sideSave());
arr.push(sideSave());
arr.push(sideSave());
Promise.all(arr).then(_ => {
console.log('all done');
});
如果你只需要一个人来实现,那就使用与这些承诺相反的方法。您可以使用辅助函数:
const invert = p => p.then(resp => { throw resp }).catch(err => err);
此函数返回一个承诺,该承诺将在其参数满足时拒绝,反之亦然。
现在你可以做到:
var arr = [importantSave()];
arr.push(sideSave());
arr.push(sideSave());
arr.push(sideSave());
invert(Promise.all(arr.map(invert))).then(_ => {
console.log('one done');
});