在JavaScript中,我们常常需要让多个异步操作按顺序依次执行,即下一个操作必须等待上一个操作完成才能开始。这在处理有依赖关系的任务(如分步上传、串联API调用)时至关重要。
![图片[1]-如何顺序执行多个异步操作?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/e6c709f1d20245b9b7a5d6b0d00f5272tplv-tb4s082cfz-aigc_resize_1080_1080-1.webp)
使用async/await的for循环
最清晰和灵活的方式是在async函数内部使用for循环来遍历你的任务集合,并在循环体内使用await等待每个任务完成。
async function sequentialTasks(tasks) {
const results = [];
for (const task of tasks) {
const result = await task(); // 等待当前任务完成
results.push(result);
}
return results;
}
// 示例任务
const task1 = () => new Promise(res => setTimeout(() => { console.log('任务1'); res(1); }, 1000));
const task2 = () => new Promise(res => setTimeout(() => { console.log('任务2'); res(2); }, 500));
sequentialTasks([task1, task2]).then(results => console.log('所有结果:', results));
输出会严格按照“任务1”、“任务2”、“所有结果: [1, 2]”的顺序出现。for循环确保了迭代的同步性,而await确保了异步操作的顺序执行。
使用reduce串联Promise
另一种函数式的方法是使用reduce。它通过将前一个Promise的结果传递给下一个Promise来构建一个串联的Promise链。
function sequentialPromise(tasks) {
return tasks.reduce((promiseChain, currentTask) => {
return promiseChain.then(chainResults =>
currentTask().then(currentResult => [...chainResults, currentResult])
);
}, Promise.resolve([]));
}
sequentialPromise([task1, task2]).then(results => console.log('串联结果:', results));
这里的reduce从一个已解决的Promise(Promise.resolve([]))开始,每次迭代都将一个新的.then()链接到链条上。这能实现同样的顺序执行,但代码逻辑比async/await版本稍显复杂。
手动构建Promise链
对于已知且固定的几个异步任务,最直接的方法就是手动await每一个。
async function fixedSequence() {
const res1 = await fetch('/api/first');
const data1 = await res1.json();
const res2 = await fetch(`/api/second/${data1.id}`);
const data2 = await res2.json();
return data2;
}
这种方法简单明了,适用于步骤明确、数量不多的场景。当步骤动态或数量可变时,前两种方法更合适。
选择方案与注意事项
使用async/await配合循环是当前最推荐的做法,它代码直观,易于添加错误处理(用try...catch包裹循环体或单个await),且性能良好。
async function sequentialWithErrorHandling(tasks) {
const results = [];
for (const task of tasks) {
try {
results.push(await task());
} catch (error) {
console.error('某个任务失败:', error);
// 决定是中断还是继续
break; // 或 continue
}
}
return results;
}
而reduce方案更函数式,但错误处理需要融入链中。无论哪种方式,其本质都是让每个异步操作在前一个操作的Promise解决后才开始,从而保证了严格的执行顺序。






















暂无评论内容