如何在Promise.all的then分支中使用await及更优实现方案
报错原因
await 仅允许在被async标记的函数内部使用,你传入.then()的回调是普通函数,内部直接使用await会触发语法错误。
基于原有链式写法的修复
如果要保留.then()的调用结构,只需要给.then()的回调函数加上async标记即可,修复后代码:
const handleSend = async ({ text, attachments }) => { Promise.all(attachments.map(async a => { const isImage = a.type.startsWith('image/'); let response = null; if (isImage) { response = await channel.sendImage(a); } else { response = await channel.sendFile(a); } return { name: a.name, path: response.file, size: a.size, isImage }; })).then(async (attachmentsArr) => { // 回调加async标记即可正常使用await await channel.sendMessage({ text, workspaceId: '1234567', attachments: attachmentsArr }); }); };
无嵌套的优雅实现
外层handleSend本身已经是async函数,完全可以直接await Promise.all的执行结果,彻底移除.then()嵌套,逻辑更扁平易读,原代码开头冗余的const attachmentsArr = null也可以直接删除,优化后逻辑和原需求完全等价,且保留了附件并发上传的性能优势:
const handleSend = async ({ text, attachments }) => { // 直接等待所有附件并发上传完成 const attachmentsArr = await Promise.all(attachments.map(async a => { const isImage = a.type.startsWith('image/'); const response = isImage ? await channel.sendImage(a) : await channel.sendFile(a); return { name: a.name, path: response.file, size: a.size, isImage }; })); // 所有附件处理完成后发送消息 await channel.sendMessage({ text, workspaceId: '1234567', attachments: attachmentsArr }); };
补充说明:以上两种写法都不会改变原逻辑的并发特性,所有附件上传请求会并行发起,总耗时为耗时最长的单个附件上传时间,而非所有附件上传耗时累加。
内容的提问来源于stack exchange,提问作者william007
相关产品推荐
相关产品推荐

