2026-05-22 多个异步任务如何“同步”执行?(deepseek)
要等待多个 fetch 或 Promise 异步操作全部完成后,再执行下一个逻辑,可以使用 Promise.all 或 Promise.allSettled。
方法对比
| 方法 | 行为 | 适用场景 |
|---|---|---|
Promise.all() |
全部成功才继续,有一个失败就立即停止 | 所有请求都必须成功,缺一不可 |
Promise.allSettled() |
等全部完成(无论成功/失败),继续执行 | 能容忍部分请求失败,需要所有结果 |
Promise.race() |
任意一个完成就继续 | 只需要最快的结果 |
1. 使用 Promise.all(全部成功才继续)
async function loadMultipleResources() {
try {
// 并发执行多个 fetch 请求
const [usersRes, postsRes, commentsRes] = await Promise.all([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
// 所有请求成功后才能进入这里
const users = await usersRes.json();
const posts = await postsRes.json();
const comments = await commentsRes.json();
console.log('所有数据加载完成:', { users, posts, comments });
// 在这里执行下一步逻辑
await nextLogic(users, posts, comments);
} catch (error) {
// 任何一个请求失败,都会进入这里
console.error('某个请求失败了:', error);
}
}
function nextLogic(users, posts, comments) {
console.log('执行后续逻辑...');
// 处理数据、渲染页面等
}
2. 使用 Promise.allSettled(容忍部分失败)
async function loadMultipleResources() {
// 并发执行,等待全部完成(无论成功或失败)
const results = await Promise.allSettled([
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
]);
// 解析所有结果
const data = {};
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
// 成功:处理数据
const response = result.value;
// 这里需要根据具体请求处理 response.json()
console.log(`请求 ${index} 成功`);
} else {
// 失败:记录错误
console.error(`请求 ${index} 失败:`, result.reason);
data[`error_${index}`] = result.reason;
}
});
// 无论部分请求是否失败,都会执行这里
console.log('所有请求已完成(可能有失败的)');
await nextLogic();
}
3. 混合场景:先并发获取数据,再处理
async function loadUserAndPosts(userId) {
try {
// 同时获取用户信息和帖子列表
const [userRes, postsRes] = await Promise.all([
fetch(`/api/users/${userId}`),
fetch(`/api/users/${userId}/posts`)
]);
const user = await userRes.json();
const posts = await postsRes.json();
console.log('用户信息:', user);
console.log('帖子列表:', posts);
// 等待所有帖子详情加载完(动态并发)
const postDetailsPromises = posts.map(post =>
fetch(`/api/posts/${post.id}`).then(res => res.json())
);
// 等待所有帖子详情加载完成
const postDetails = await Promise.all(postDetailsPromises);
console.log('所有帖子详情:', postDetails);
// 最后执行渲染逻辑
renderPage(user, posts, postDetails);
} catch (error) {
console.error('加载失败:', error);
}
}
4. 使用 Promise.all + 数据处理
async function fetchAndProcess() {
// 定义多个请求
const requests = [
fetch('/api/data1'),
fetch('/api/data2'),
fetch('/api/data3')
];
try {
// 等待所有请求完成
const responses = await Promise.all(requests);
// 并行解析 JSON(不需要等待彼此)
const data = await Promise.all(
responses.map(res => res.json())
);
console.log('所有数据解析完成:', data);
// 执行后续逻辑
processData(data);
} catch (error) {
console.error('请求或解析失败:', error);
}
}
5. 实际场景:批量更新表格数据
// 你项目中的实际场景:批量更新多个记录的批次号
async function batchUpdateBatchNos(records) {
// 构建所有更新请求
const updatePromises = records.map(record =>
fetch('/api/update-batch', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: record.id, batchno: record.eo45_batchno })
}).then(res => {
if (!res.ok) throw new Error(`更新失败: ${record.id}`);
return res.json();
})
);
try {
// 等待所有更新完成
const results = await Promise.all(updatePromises);
console.log('所有批次更新成功:', results);
// 刷新表格
await refreshTable();
showMessage('批量更新完成');
} catch (error) {
console.error('批量更新失败:', error);
showMessage('部分更新失败,请重试');
}
}
6. 带重试机制的并发请求
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const res = await fetch(url);
if (res.ok) return res;
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(r => setTimeout(r, 1000 * (i + 1))); // 延迟重试
}
}
}
async function loadMultipleWithRetry(urls) {
const results = await Promise.allSettled(
urls.map(url => fetchWithRetry(url))
);
const successful = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
console.log(`成功: ${successful.length}, 失败: ${failed.length}`);
return { successful, failed };
}
总结
| 你的需求 | 推荐方案 |
|---|---|
| 全部成功才继续,有一个失败就停止 | Promise.all() |
| 容忍部分失败,等待全部完成 | Promise.allSettled() |
| 需要逐次处理(有依赖关系) | 用 await 分别调用,或用 for...of 循环 |
| 大量并发请求(如 >10 个) | 使用 p-limit 等库限制并发数 |
最常用的模式:
const [data1, data2, data3] = await Promise.all([
fetch('/api/1').then(r => r.json()),
fetch('/api/2').then(r => r.json()),
fetch('/api/3').then(r => r.json())
]);
// 三个请求都完成后执行这里

浙公网安备 33010602011771号