实现思路
- 并发任务执行:使用
Promise.all
来并发执行任务A、B、C。Promise.all
会返回一个新的Promise,只有当传入的所有Promise都resolved时,这个新Promise才会resolved,并且其resolved的值是一个包含所有传入Promise resolved值的数组。
- 依赖任务执行:在
Promise.all
成功后,执行任务D,并将任务A、B、C的结果作为参数传递给任务D。
- 错误处理:为了全面处理错误并收集错误信息,使用
try...catch
块来捕获每个任务可能抛出的错误。在 catch
块中,将错误信息收集到一个数组中,并根据需求决定是否继续执行其他并发任务(例如任务B和C)。
- 链式调用中的错误处理:在整个链式调用中,确保每个
then
方法都有对应的 catch
方法,避免错误在链式调用中被遗漏处理。
代码示例
function taskA() {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() < 0.5? resolve('A result') : reject(new Error('A error'));
}, 1000);
});
}
function taskB() {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() < 0.5? resolve('B result') : reject(new Error('B error'));
}, 1000);
});
}
function taskC() {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() < 0.5? resolve('C result') : reject(new Error('C error'));
}, 1000);
});
}
function taskD(aResult, bResult, cResult) {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() < 0.5? resolve(`D result: ${aResult}, ${bResult}, ${cResult}`) : reject(new Error('D error'));
}, 1000);
});
}
function executeTasks() {
const errorList = [];
return Promise.all([taskA(), taskB(), taskC()])
.then(([aResult, bResult, cResult]) => {
return taskD(aResult, bResult, cResult);
})
.catch((error) => {
errorList.push(error);
// 这里可以根据需求决定是否继续执行其他任务
// 例如:忽略任务A的错误,继续执行任务B和C
return Promise.all([taskB(), taskC()])
.then(([bResult, cResult]) => {
return taskD(null, bResult, cResult);
})
.catch((innerError) => {
errorList.push(innerError);
return Promise.reject(errorList);
});
});
}
executeTasks()
.then((result) => {
console.log('Final result:', result);
})
.catch((errors) => {
console.log('All errors:', errors);
});
对Promise并发和错误传播机制的理解
- Promise并发:
Promise.all
允许并发执行多个Promise任务。它会等待所有传入的Promise都resolved后,返回一个resolved的Promise,其值为所有传入Promise resolved值组成的数组。这大大提高了任务执行效率,因为多个任务可以同时进行,而不需要等待前一个任务完成。
- 错误传播机制:当
Promise.all
中的任何一个Promise被rejected时,整个 Promise.all
会立即被rejected,并且其rejected的值就是第一个被rejected的Promise的rejected值。在链式调用中,错误会沿着 .then()
链一直传递,直到遇到一个 .catch()
块来处理它。如果没有 .catch()
块,错误会导致未处理的拒绝(unhandled rejection),这可能会导致程序出现难以调试的问题。因此,在编写Promise链式调用时,确保每个 then
方法都有对应的 catch
方法,或者在链的末尾添加一个全局的 catch
块来处理可能遗漏的错误,是非常重要的。