Node.js中使用Promise.all执行多S3写入操作失效问题排查
问题排查与解决方案
核心问题1:所有上传请求使用相同的S3 Key
你在批量上传时给所有文件都用了'some-random-key'作为Key,S3的Key是存储对象的唯一标识,并发上传同一个Key会导致:
- 后发起的请求会覆盖先发起的,最终只有一份文件成功上传
- 并发写入同一Key可能触发S3的冲突拦截,导致部分请求被提前终止,无法走到打印
result.Location的步骤
修复方式:给每个上传的item生成唯一Key,比如结合item的唯一标识或者时间戳:
await this.s3Repository.uploadData( item, `unique-key-${item.id}-${Date.now()}` // 用item的唯一ID+时间戳生成Key )
核心问题2:外层异步逻辑未被正确等待
如果包含这段Promise.all代码的函数本身是async函数,但调用这个函数的地方没有用await,或者这段代码直接写在脚本顶层(Node.js环境中),会导致Node.js事件循环在所有S3上传Promise完成前就退出,程序终止,自然看不到后续的console.log(result.Location)输出。
修复方式:
- 如果这段代码在一个async函数内,确保调用该函数时使用
await:async function batchUpload() { if (s3Payload.length > 0) { await Promise.all(_.map(s3Payload, async (item)=>{ await this.s3Repository.uploadData( item, `unique-key-${item.id}` ) })); } } // 调用时必须await await batchUpload(); - 如果是Node.js脚本顶层,Node.js 14.8+支持顶层await,直接用即可;低于该版本的话,需要包裹在async IIFE中:
(async () => { if (s3Payload.length > 0) { await Promise.all(_.map(s3Payload, async (item)=>{ await this.s3Repository.uploadData( item, `unique-key-${item.id}` ) })); } })();
额外验证点:检查S3客户端初始化是否正确
确保你的S3客户端实例(this.s3)已经正确配置了AWS凭证、区域等参数,虽然当前日志显示calling s3已经执行,但如果客户端配置有问题,可能导致请求卡在发送阶段,最终程序超时退出。可以在catch块中增加更详细的错误日志:
catch (err) { console.error('S3上传失败:', err); // 打印详细错误信息 return { "statusCode": 500, "errorMessage": err }; }
内容的提问来源于stack exchange,提问作者Naxi
相关产品推荐
相关产品推荐

