forEach和await組合使用
const userIds = [1, 2, 3];
async function updateUserStatus(id) {
console.log(`開始更新用戶${id}`);
// 模擬一個(gè)需要 1 秒的網(wǎng)絡(luò)請求
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);
輸出結(jié)果:
1.開始批量更新
2.所有用戶更新完畢!
開始更新用戶1
開始更新用戶2
開始更新用戶3
// 等待約1秒后
用戶1更新成功!
用戶2更新成功!
用戶3更新成功!
方案一:for...of循環(huán)(順序執(zhí)行)
async function batchUpdateUsersInOrder(ids) {
console.log("開始批量更新 (順序執(zhí)行) ");
for (const id of ids) {
// 這里的 await 會實(shí)實(shí)在在地暫停 for 循環(huán)的下一次迭代
await updateUserStatus(id);
}
console.log("所有用戶更新完畢!");
}
方案二:Promise.all+ map(并行執(zhí)行)
async function batchUpdateUsersInParallel(ids) {
console.log("開始批量更新 (并行執(zhí)行) ");
// 1. map 會立即返回一個(gè) Promise 數(shù)組
const promises = ids.map(id => updateUserStatus(id));
// 2. Promise.all 會等待所有 promises 完成
await Promise.all(promises);
console.log("所有用戶更新完畢!(這次是真的,而且很快) ");
}
方案三:for循環(huán)或for...in循環(huán)(更靈活的)
// 傳統(tǒng) for 循環(huán)
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)
}
})
})
}
// 遍歷數(shù)組并調(diào)用接口
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);
}
}
}
// 執(zhí)行遍歷和接口調(diào)用
const list = [1, 2, 3, 4, 5]
fetchDataInfos(list)