forEach里用await的坑

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)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • js遍歷數(shù)組常用基本就是 map,reduce,forEach,for...of map 針對是返回值處理情況,關(guān)...
    pruple_Boy閱讀 515評論 0 0
  • 1、項(xiàng)目中亮點(diǎn)(難點(diǎn)) 在項(xiàng)目中用ECharts畫的可視化大屏的時(shí)候,里面的字體在調(diào)整瀏覽器大小的時(shí)候無法做到適配...
    f360f8fc4fbb閱讀 117評論 0 0
  • 0 HTML5相關(guān) websocket WebSocket 使用ws或wss協(xié)議,Websocket是一個(gè)持久化的...
    可愛多小姐閱讀 1,003評論 0 0
  • 原型鏈的理解 看一個(gè)實(shí)例 原型和原型鏈?zhǔn)紫纫缼讉€(gè)概念:在js里,繼承機(jī)制是原型繼承。繼承的起點(diǎn)是 對象的原型(...
    __bomb__閱讀 165評論 0 0
  • 22. 如何判斷一個(gè)對象是否屬于某個(gè)類? ●第一種方式,使用 instanceof 運(yùn)算符來判斷構(gòu)造函數(shù)的 pro...
    稚沅閱讀 175評論 0 0

友情鏈接更多精彩內(nèi)容