Node.js新版本中AWS Lambda函数await Promise.all未执行无报错如何解决
核心问题清单
- 未捕获的同步错误导致进程提前终止
你的代码存在多处未定义变量,且核心逻辑未被try/catch覆盖:第一处
await getOrder(sql, 0)中的sql变量未定义,抛出ReferenceError进入catch块后,仅调用了callback(error)没有加return,代码会继续向下执行;后续_.countBy(followingsIDs, groupKey)中的followingsIDs变量、lodash对象_均未定义,这段逻辑在try/catch外部,抛出的错误没有被捕获。新版Node.js对未捕获的同步错误、未处理的Promise rejection会直接终止进程,旧版仅输出警告,这是升级后Promise.all代码段完全不执行的核心原因。 - async handler混用callback不符合新版Lambda运行时规范
AWS Lambda新版Node.js运行时对async类型handler的处理规则有变更:如果用async关键字声明handler,运行时会优先等待函数返回的Promise状态变更,忽略callback的调用结果,混用两种返回方式会导致执行时序不符合预期。async handler不需要调用callback,直接return执行结果、throw错误即可。
- 数据库连接异常未正确接入Promise链
getOrder方法中,pool.getConnection报错时直接throw err,该错误不会被外层Promise捕获,会成为未捕获异常导致进程退出,应该改为reject(err)将错误传入Promise链。 - 异步操作缺await导致Promise提前决议
如果
dosomething()是异步方法,未加await的话,map返回的异步函数会提前resolve,内部后续的数据库写入、SNS发送逻辑可能还没执行完,Promise.all就已经结束。 - 潜在的空数组问题
如果
uniqResult是空数组,Promise.all会直接resolve,内部的逻辑自然不会执行,可以先打印uniqResult.length确认数组是否为空。
修复后代码参考
let AWS = require('aws-sdk'); const _ = require('lodash'); // 补全lodash导入 const sns = new AWS.SNS(); // 补全sns实例初始化 // 补全sql、followingsIDs、pool、params、response等你代码中未定义的变量 exports.handler = async(event, context) => { let result = {}; try { // 补全sql变量定义后再调用 result = await getOrder(sql, 0); result.map((dataField) => { // 你的原有逻辑 }); var today_result = []; const groupKey = i => i.user_id + '_' + i.when; // 补全followingsIDs变量定义后再调用 const counts = _.countBy(followingsIDs, groupKey); const isMulti = i => counts[groupKey(i)] > 1; const multiPropkey = i => ({ multiplekey: groupKey(i) }); const multiProp = i => ({ multiple: isMulti(i) ? counts[groupKey(i)] : 1 }); const updated = _.map(followingsIDs, i => _.extend(i, multiProp(i), multiPropkey(i))); const uniqResult = _.uniq(updated, function(d) { return d.multiplekey }); console.log('uniqResult长度:', uniqResult.length); // 确认是否为空数组 await Promise.all(uniqResult.map(async(dataField) => { console.log("test_"); // 如果dosomething是异步方法,要加await await dosomething() if (true) { let sql = `INSERT INTO ….` result = await getOrder(sql, 0); try { const data = await sns.publish(params).promise(); } catch (e) { console.log(e.stack); response.result = 'Error'; } } })); // async handler直接return结果,不需要callback return uniqResult; } catch (error) { console.log(error); // async handler直接throw错误,不需要callback throw error; } }; let getOrder = async(sql, params) => { return new Promise((resolve, reject) => { pool.getConnection((err, connection) => { if (err) { // 连接错误用reject传入Promise链,不要直接throw return reject(err); } connection.query(sql, params, (err, results) => { connection.release(); if (err) { return reject(err); } resolve(results); }); }); }); };
内容的提问来源于stack exchange,提问作者adimona

