一、原始代码的行为(使用 async/await
)
javascript
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
,代码会变成:
javascript
const getUserMessagePlan = () => {
// 直接获取 Promise 对象(未等待结果)
const tabsList = message.getTagesList(); // 返回未完成的 Promise
const tagsStateList = message.getTagsStateList(); // 同上
// 此时 tabsList 和 tagsStateList 是 Promise 对象,而非实际数据
const tempMessageList = [];
for (let i = tabsList.length - 1; i >= 0; i--) { // ❌ 报错:tabsList 是 Promise,无 length
const user = message.getUserInfo(tabsList[i].senderId); // 同样返回 Promise
const 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
(推荐)
保持原有逻辑,确保异步操作按顺序执行:
javascript
const getUserMessagePlan = async () => {
const [tabsList, tagsStateList] = await Promise.all([
message.getTagesList(),
message.getTagsStateList()
]);
// 并行请求优化(减少总耗时)
// ...
};
方案二:改用 Promise.then()
链式调用
若不使用 async/await
,需手动处理 Promise 链:
javascript
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
),但不可省略异步控制关键字。