使用Array.map生成异步任务时Promise.all未等待resolve就提前执行
问题根因
当前代码存在几处直接导致异常的错误:
- AWS SDK 用法不规范:同时给
sqs.sendMessage传入回调函数、又链式调用.promise(),两种异步处理方式混用会让SDK回调触发逻辑不可控,最终手动包裹的Promise状态异常 - 多余的手动Promise包裹:AWS SDK的
.promise()本身就会返回标准Promise,不需要额外用new Promise()再套一层,徒增出错概率 - 错误处理逻辑缺陷:回调中捕获到错误执行
reject(err)后没有return,会继续执行后续的resolve(data)代码,属于不规范写法 - 最终
Array.map生成的数组中混入了非Promise值或提前resolve的Promise,导致Promise.all无法正确等待所有任务完成。
修复方案
直接使用AWS SDK原生的Promise接口,移除多余的包裹逻辑,规范错误处理:
// 重写后的 newMessage 函数 const newMessage = async (params) => { try { console.log('sending') // 仅用SDK自带的promise()方法,不传回调,避免混用 const result = await sqs.sendMessage(params).promise() console.log('Sent') return result } catch (err) { console.error('发送失败', err) // 抛出错误,让Promise.all可以正常捕获异常 throw err } } // 生成Promise数组,此时每个元素都是pending状态的Promise const taskList = messageData.map(item => newMessage(item)) // 等待所有任务完成后再执行后续逻辑 await Promise.all(taskList)
注意:如果你的
messageData中的元素不是直接可用于sqs.sendMessage的参数结构,必须在map的回调中手动拼接参数,不要直接把newMessage作为map的回调(否则map会把元素、索引、原数组三个参数都传给newMessage,导致参数异常)。
内容的提问来源于stack exchange,提问作者Elliott Hinschen-Teeuwen
相关产品推荐
相关产品推荐

