一、原始代碼的行為(使用 async/await
)
const getUserMessagePlan = async () => {// 等待兩個異步操作完成const tabsList = await message.getTagesList(); // 等待獲取標簽列表const tagsStateList = await message.getTagsStateList(); // 等待獲取狀態列表// 后續代碼在數據就緒后執行const tempMessageList = [];for (let i = tabsList.length - 1; i >= 0; i--) {const user = await message.getUserInfo(tabsList[i].senderId); // 等待獲取用戶信息// 構造數據對象const t = { ... };tempMessageList.push(t);}userMessageList.value = sortData(tempMessageList);
};
? 關鍵特性:
? await
會暫停當前函數的執行,直到 Promise 完成,并按順序解析結果。
? 所有異步操作(如網絡請求)會按代碼順序依次執行,確保數據就緒后才進行后續處理。
二、刪除 async/await
的后果
若直接刪除 async/await
,代碼會變成:
const getUserMessagePlan = () => {// 直接獲取 Promise 對象(未等待結果)const tabsList = message.getTagesList(); // 返回未完成的 Promiseconst tagsStateList = message.getTagsStateList(); // 同上// 此時 tabsList 和 tagsStateList 是 Promise 對象,而非實際數據const tempMessageList = [];for (let i = tabsList.length - 1; i >= 0; i--) { // ? 報錯:tabsList 是 Promise,無 lengthconst user = message.getUserInfo(tabsList[i].senderId); // 同樣返回 Promiseconst t = { ... }; // 此時 user 是未完成的 Promise,數據無效tempMessageList.push(t); // 填充無效數據}userMessageList.value = sortData(tempMessageList); // 數據混亂
};
? 具體問題:
- Promise 未被解析:
tabsList
和tagsStateList
會直接返回 Promise 對象,而非實際數據。 - 循環邏輯崩潰:嘗試訪問
tabsList.length
時會報錯,因為tabsList
是 Promise(沒有length
屬性)。 - 數據無效:
message.getUserInfo
返回的 Promise 未被等待,user
變量將是一個未完成的 Promise,無法獲取uid
、avatar
等字段。 - 最終結果錯誤:
tempMessageList
中填充的是 Promise 對象,而非真實數據,導致渲染或后續處理失敗。
三、如何正確優化?
方案一:保留 async/await
(推薦)
保持原有邏輯,確保異步操作按順序執行:
const getUserMessagePlan = async () => {const [tabsList, tagsStateList] = await Promise.all([message.getTagesList(),message.getTagsStateList()]);// 并行請求優化(減少總耗時)// ...
};
方案二:改用 Promise.then()
鏈式調用
若不使用 async/await
,需手動處理 Promise 鏈:
const getUserMessagePlan = () => {message.getTagesList().then(tabsList => message.getTagsStateList().then(tagsStateList => {const tempMessageList = [];const promises = tabsList.map((tab, i) => message.getUserInfo(tab.senderId).then(user => ({uid: user.uid,// ...})));return Promise.all(promises);})).then(tempMessageList => {userMessageList.value = sortData(tempMessageList);});
};
? 缺點:代碼嵌套復雜,可讀性差。
四、總結
? 必須使用異步控制:async/await
或 Promise.then()
是處理異步操作的唯一可靠方式。
? 刪除 async/await
的后果:數據未就緒時執行后續代碼,導致邏輯錯誤和渲染異常。
? 優化建議:若需提升性能,可并行請求(如 Promise.all
),但不可省略異步控制關鍵字。