forEach和await组合使用
const userIds = [1, 2, 3];
async function updateUserStatus(id) {
console.log(`开始更新用户${id}`);
// 模拟一个需要 1 秒的网络请求
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(`用户 ${id} 更新成功!`);
return { success: true };
}
async function batchUpdateUsers(ids) {
console.log("1.开始批量更新");
ids.forEach(async (id) => {
await updateUserStatus(id);
});
console.log("2.所有用户更新完毕!"); // 问题的根源在这里!
}
batchUpdateUsers(userIds);
输出结果:
1.开始批量更新
2.所有用户更新完毕!
开始更新用户1
开始更新用户2
开始更新用户3
// 等待约1秒后
用户1更新成功!
用户2更新成功!
用户3更新成功!
方案一:for...of循环(顺序执行)
async function batchUpdateUsersInOrder(ids) {
console.log("开始批量更新 (顺序执行) ");
for (const id of ids) {
// 这里的 await 会实实在在地暂停 for 循环的下一次迭代
await updateUserStatus(id);
}
console.log("所有用户更新完毕!");
}
方案二:Promise.all+ map(并行执行)
async function batchUpdateUsersInParallel(ids) {
console.log("开始批量更新 (并行执行) ");
// 1. map 会立即返回一个 Promise 数组
const promises = ids.map(id => updateUserStatus(id));
// 2. Promise.all 会等待所有 promises 完成
await Promise.all(promises);
console.log("所有用户更新完毕!(这次是真的,而且很快) ");
}
方案三:for循环或for...in循环(更灵活的)
// 传统 for 循环
for (let i = 0; i < ids.length; i++) {
await updateUserStatus(ids[i]);
}
推荐方案:
// 请求接口
const getDataInfo = async (type) => {
return new Promise((resolve) => {
searchDataInfo({
type,
pageNum: 1,
pageSize: 10
}).then(res => {
if (res?.code === 200) {
resolve(res.data)
} else if (res?.msg) {
console.log(res?.msg, null, 5, res?.code)
}
})
})
}
// 遍历数组并调用接口
const fetchDataInfos = async (list) => {
for (let item of list) {
try {
const itemData = await getDataInfo(item)
} catch (error) {
console.error(`Failed to fetch item info for item ${item}`, error);
}
}
}
// 执行遍历和接口调用
const list = [1, 2, 3, 4, 5]
fetchDataInfos(list)