我正在使用以下代码段执行多个promise:
await Promise.all([promise1, promise2, promise3]);
我想实现的是回退成功承诺对Promise.all()
失败的影响。
用更具体的术语来说,这意味着上述操作将对文件进行一些加密,但是如果其中一个失败,我想删除另外两个(或一个)已成功加密的文件,以使文件组保持一致且干净。>
根据我的阅读,这意味着我需要两个步骤:
1.捕获每个承诺的错误,以使Promise.all()
不会引发错误。
2.令人困惑的部分:还有另一种Promise.all()
:
await Promise.all([rollbackPromise1, rollbackPromise2, rollbackPromise3]);
这似乎是棘手的部分:我是否应该独立于失败的诺言执行所有回滚?这意味着我应对每个错误进行另一个捕获,以使Promise.all()
等待每次回滚完成。
这是执行此操作的最佳方法,我发现它在代码方面非常低效且难看。
答案 0 :(得分:1)
您可以创建自己的函数,以实现对函数的异步调用并在需要时执行回滚。
// Function that'll perform a promise.all and rollback if required
async function allWithRollback(promises) {
// using the map we are going to wrap the promise inside of a new one
return Promise.all(promises.map(([
func,
rollbackFunc,
], xi) => ((async() => {
try {
await func;
console.log('One Function succeed', xi);
} catch (err) {
console.log('One Function failed, require rollback', xi);
await rollbackFunc();
}
})())));
}
// Call the custom Promise.all
allWithRollback([
[
// First param is the promise
okPromise(),
// Second param is the rollback function to execute
() => {},
],
[okPromise(), () => {}],
[errPromise(), rollback1],
[errPromise(), rollback2],
[okPromise(), () => {}],
]);
// ---------
async function okPromise() {
return true;
}
async function errPromise() {
throw new Error('no one read this');
}
async function rollback1() {
console.log('Performed the rollback1');
}
async function rollback2() {
console.log('Performed the rollback2');
}
答案 1 :(得分:0)
您可以如下创建一个简单的解决方案:
const errorHandlers = []
function enc1 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('str')
}, 1000)
errorHandlers.push(() => {
console.log('handler 1')
})
})
}
function enc2 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('str')
}, 2000)
errorHandlers.push(() => {
console.log('handler 2')
})
})
}
function enc3 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('str')
}, 3000)
errorHandlers.push(() => {
console.log('handler 3')
})
})
}
Promise.all([enc1(), enc2(), enc3()]).then(() => {
console.log('all resovled')
}).catch((e) => {
errorHandlers.forEach(handler => handler(e))
})
它将为您提供处理每个承诺中的“全局”错误的选项。在创建全部承诺之前,您可以重置errorHandlers以防止执行多个errorHandler