Node.js嵌套Promise问题:AWS Lambda双Promise执行异常排查
AWS Lambda中Promise嵌套与异步等待的问题排查
我在AWS Lambda中使用Node.js代码,期望等待
sendMessage和updateStatus两个返回Promise的函数执行完成,但日志仅显示@@BP12.1、BP1-1、BP1-2,未出现BP1-3、BP1-4、BP1-5,无证据表明静态方法MessagingSession.getAccessToken被调用。我通过Promise.all合并两个Promise,想知道Promise嵌套存在什么错误?
原代码如下:
exports.handler = async(event, context, callback) => { ... console.info('@@BP12.1: '); var statusTypeName = 'AVAILABLE'; (async() => { await Promise.all([sendMessage(event), updateStatus(event, statusTypeName).promise]); })(); ... } async function sendMessage(payload) { const promise = new Promise(function(resolve, reject) { console.info('@@BP1-1'); let argumentParserResult = { ...}; console.info('@@BP1-2'); let accessToken = MessagingSession.getAccessToken(argumentParserResult).then((accessTokenResponse) => { console.info('@@BP3'); argumentParserResult.accessToken = accessTokenResponse.access_token; let messagingSession = new MessagingSession(MessagingSession.getInitializedSolaceModule(), argumentParserResult); console.info('@@BP4'); resolve(messagingSession); }).catch(error => { console.info('@@BP5'); console.info("Error fetching access token: " + error); reject(error); }) }); return promise; }
核心问题分析
- 匿名异步函数未被等待:Lambda的handler本身是async函数,但你在内部创建了一个匿名立即执行异步函数,却没有用
await等待它完成。Lambda执行环境会在handler函数执行完毕后,直接终止进程,导致后续异步操作还没启动就被中断,这就是getAccessToken无日志的根本原因。 - Promise嵌套反模式:
sendMessage本身已经是async函数,没必要手动创建新Promise。这种冗余嵌套不仅增加复杂度,还可能导致错误捕获不完整,出现Promise永久pending的情况。
修正方案
1. 修复handler的异步等待逻辑
去掉多余的匿名嵌套函数,直接在handler中await Promise.all:
exports.handler = async(event, context, callback) => { // ...其他代码 console.info('@@BP12.1: '); var statusTypeName = 'AVAILABLE'; // 直接等待Promise.all完成,无需额外嵌套async函数 await Promise.all([sendMessage(event), updateStatus(event, statusTypeName).promise]); // ...其他代码 }
2. 简化sendMessage函数,消除冗余Promise
利用async函数天然返回Promise的特性,用await替代手动Promise嵌套:
async function sendMessage(payload) { console.info('@@BP1-1'); let argumentParserResult = { /* ...你的对象内容 */ }; console.info('@@BP1-2'); try { const accessTokenResponse = await MessagingSession.getAccessToken(argumentParserResult); console.info('@@BP3'); argumentParserResult.accessToken = accessTokenResponse.access_token; const messagingSession = new MessagingSession(MessagingSession.getInitializedSolaceModule(), argumentParserResult); console.info('@@BP4'); return messagingSession; } catch (error) { console.info('@@BP5'); console.info("Error fetching access token: " + error); throw error; // 抛出错误让Promise.all统一处理 } }
额外注意事项
- Lambda的async handler无需依赖
callback参数,直接返回值或抛出错误即可完成响应。 - 确保
updateStatus(event, statusTypeName).promise是有效的Promise对象,否则会导致Promise.all异常或提前结束。
内容的提问来源于stack exchange,提问作者Woodsman
相关产品推荐
相关产品推荐

