异步调用另一个lambda的aws lambda

Abd*_*naf 14 asynchronous asynccallback amazon-web-services node.js aws-lambda

我需要异步调用另一个lambda的aws lambda.我有一个同步调用的工作代码.

exports.handler = (event, context, callback) => {
    var aws = require('aws-sdk');
    var lambda = new aws.Lambda({
        region: 'myregion' //change to your region
    });
    console.log("lambda invoke started");
    lambda.invoke({
        FunctionName: 'testLambda',
        Payload: JSON.stringify(event, null, 2) // pass params
    }, function (error, data) {
        if (error) {
            console.log("error");
            callback(null, 'hello world');
        }
        else {
            console.log("lambda invoke end");
            callback(null, 'hello world');
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

但就我而言,'testLambda'是一个耗时的功能.因为我需要在调用'testLambda'函数后退出.然后代码就像这样更新

exports.handler = (event, context, callback) => {
    var aws = require('aws-sdk');
    var lambda = new aws.Lambda({
        region: 'myregion' //change to your region
    });
    console.log("lambda invoke started");
    lambda.invoke({
        FunctionName: 'testLambda',
        Payload: JSON.stringify(event, null, 2) // pass params
    });
    console.log("lambda invoke end");
    callback(null, 'hello world');
}
Run Code Online (Sandbox Code Playgroud)

它正确地返回消息.但是我的'testLambda'函数没有被调用(没有为测试lambda生成云监视日志).与此代码相关的问题是什么?

Mar*_*k B 14

根据Lambda invoke()文档,您将看到默认情况下使用RequestResponse调用类型调用Lambda函数.要异步调用函数,您需要指定Event调用类型,如下所示:

lambda.invoke({
    FunctionName: 'testLambda',
    InvocationType: 'Event',
    Payload: JSON.stringify(event, null, 2)
},function(err,data){});
Run Code Online (Sandbox Code Playgroud)


ron*_*nat 7

我正在使用AWS Lambda中当前最新的node.js 8.10版本。
直到我使用了异步/等待机制,第二个lambda才执行(并且从未调用过回调函数)。
因此,处理程序函数必须是异步的,并且'lambda.invoke'调用必须用Promise包装。

这是我的工作代码:

function invokeLambda2(payload) {
    const params = {
        FunctionName: 'TestLambda2',
        InvocationType: 'Event',
        Payload: JSON.stringify(payload)
    };

    return new Promise((resolve, reject) => {

        lambda.invoke(params, (err,data) => {
            if (err) {
                console.log(err, err.stack);
                reject(err);
            }
            else {
                console.log(data);
                resolve(data);
            }
        });     
    });
}


exports.handler = async (event, context) => {
    const payload = {
        'message': 'hello from lambda1'
    };
    await invokeLambda2(payload);
    context.done();
};
Run Code Online (Sandbox Code Playgroud)

请注意,处理程序不会等待第二个lambda退出,而只是等待它被触发并调用回调函数。

您也可以从处理程序中返回Promise,而不必在第二个函数中使用await

使用Promises和async / await时不需要导入,除了:

const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
Run Code Online (Sandbox Code Playgroud)

  • 当您收到 AccessDeniedException 时,不要忘记将“AWSLambdaRole”策略添加到您的 IAM 角色。{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "lambda:InvokeFunction" ], "Resource": [ "*" ] } ] } (2认同)
  • 工作起来就像一个魅力,只是一个旁注,异步调用的良好响应是:“INFO { StatusCode:202,Payload:'' }”(来自 CloudWatch Logs) (2认同)

小智 5

参考Ronginat 的回答lambda.invoke()您可以直接使用lambda.invoke().promise()并执行以下操作,而不是用 Promise包装:(在 Node.js 12.x 中测试)

exports.handler = async (event) => {

    const payload = 'hello from lambda 1';

    const params = {
        FunctionName: 'lambda2',
        InvocationType: 'Event',
        Payload: JSON.stringify(payload),
    };

    const LambdaPromise = (params) => lambda.invoke(params).promise();

    const responseFromLambda2 = await LambdaPromise(params);

    return responseFromLambda2; //this should return {StatusCode: 202, Payload: ''}
};
Run Code Online (Sandbox Code Playgroud)