NodeJS/Typescript如何正确获取lambda.invoke调用的返回值
问题原因
你踩的是NodeJS异步执行的基础时序坑:lambda.invoke是异步非阻塞API,传入的回调函数会等AWS接口返回结果后才触发,完全不会阻塞后续同步代码的执行。
你的代码实际执行顺序是:
- 初始化变量
output_lambda,赋值为'output of lambda' - 发起Lambda调用请求,不会等待请求返回,直接执行下一行代码
- 执行
console.log(output_lambda),此时回调函数还没触发,打印的自然是初始值 - 等几百毫秒Lambda返回结果后,才会执行你写的回调逻辑修改
output_lambda,但这时候打印操作早就跑完了
另外你在回调里写的return output_lambda没有任何实际作用,这个返回值只会被AWS SDK内部消费,根本传不到外层作用域。
可行方案
异步接口的返回值永远不可能在同步代码流里直接拿到,你可以选以下两种常用写法实现需求:
写法1:回调嵌套(原生SDK默认写法)
所有依赖Lambda返回值的后续逻辑,全部放到回调函数内部执行,记得优先处理调用错误:
const AWS = require('aws-sdk'); AWS.config.region = 'us-east-1'; // 替换为你实际的部署区域 const lambda = new AWS.Lambda(); const params = { FunctionName: 'arn:aws:lambda:us-east-1:XXXXXXXXXXXX:function:random-function', InvocationType: 'RequestResponse', // 同步调用模式才能拿到返回值 LogType: 'Tail', Payload: JSON.stringify({"text": 'test 123'}) }; lambda.invoke(params, function(err, data) { if (err) { console.error('Lambda调用失败:', err); return; } // Payload返回的是JSON字符串,解析后就是目标Lambda的返回结果 const lambdaResult = JSON.parse(data.Payload); // 所有需要用到lambdaResult的逻辑全部写在这里 console.log('实际返回结果:', lambdaResult); });
写法2:async/await(推荐写法,逻辑更清晰)
当前NodeJS运行时全版本支持async/await语法,你可以把回调包装成Promise,用类同步的写法写异步逻辑,避免回调嵌套的问题:
const AWS = require('aws-sdk'); AWS.config.region = 'us-east-1'; // 替换为你实际的部署区域 const lambda = new AWS.Lambda(); // 封装invoke为Promise方法 function invokeLambda(params) { return new Promise((resolve, reject) => { lambda.invoke(params, (err, data) => { if (err) return reject(err); resolve(JSON.parse(data.Payload)); }); }); } async function runLogic() { const params = { FunctionName: 'arn:aws:lambda:us-east-1:XXXXXXXXXXXX:function:random-function', InvocationType: 'RequestResponse', LogType: 'Tail', Payload: JSON.stringify({"text": 'test 123'}) }; try { // 等待调用完成后再往下执行,可直接拿到返回值供后续逻辑使用 const lambdaOutput = await invokeLambda(params); console.log('实际返回结果:', lambdaOutput); // 后续所有依赖lambdaOutput的逻辑直接往下写即可,不需要嵌套 } catch (err) { console.error('Lambda调用失败:', err); } } runLogic();
补充提示:如果你这段代码本身就运行在Lambda函数中,直接把handler定义为async函数即可,不需要额外封装runLogic方法,直接await封装好的invoke方法就行。另外要确保发起调用的Lambda执行角色拥有
lambda:InvokeFunction权限,否则会报权限错误。
内容的提问来源于stack exchange,提问作者Zeke John
相关产品推荐
相关产品推荐

