异步调用另一个lambda的aws lambda

时间:2016-08-24 14:49:20

标签: node.js amazon-web-services asynchronous aws-lambda asynccallback

我需要异步调用另一个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');
        }
    });
}

但就我而言,' 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');
}

它正确地返回消息。但是我的测试兰巴达'未调用函数(不为测试lambda生成云监视日志)。与此代码相关的问题是什么?

5 个答案:

答案 0 :(得分:7)

the Lambda invoke() documentation,您将看到默认情况下使用RequestResponse调用类型调用Lambda函数。要异步调用该函数,您需要指定Event调用类型,如下所示:

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

答案 1 :(得分:3)

参考Ronginat's answer,您可以直接使用lambda.invoke()并执行以下操作,而不是将lambda.invoke().promise()包装在Promise中:(在Node.js 12.x中进行了测试)< / p>

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: ''}
};

答案 2 :(得分:2)

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

这是我的工作代码:

logback.xml

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

您还可以从处理程序中返回 Promise ,而不必将 await 与第二个函数一起使用。

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

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();
};

答案 3 :(得分:2)

这就是我在Express.js中使用的方式


var express = require("express");
var router = express.Router();

const asyncMiddleware = fn =>
  (req, res, next) => {
    Promise.resolve(fn(req, res, next))
      .catch(next);
  };

const invokeLambda = async (params) => {
  const data = await lambda.invoke(params).promise();
  return JSON.parse(data.Payload);
}


router.get('/test', asyncMiddleware(async (req, res, next) => {
  const params = {
    FunctionName: SOMETHING_LAMBDA_ARN,
    Payload: JSON.stringify(req.body)
  };
  const result = await invokeLambda(params);
  res.send(result);
}));

答案 4 :(得分:1)

我想要一个与上述类似的解决方案。尽管现在建议在lambda.invoke上使用多个lambda函数时,建议使用step函数,但我还是使用以下代码段从基本lambda函数中异步调用了另外两个lambda函数。

var AWS = require('aws-sdk');
AWS.config.region = 'ap-southeast-1';
var lambda = new AWS.Lambda();

exports.handler = async(event) => {
   await invokeLambda(event);
   
   const response = {
        statusCode: 200,
        body: JSON.stringify('success'),
   };
   
   return response;
};

//Invoke Multiple Lambda functions
  async function invokeLambda(event) {
    const function1 = {
        FunctionName: 'dev-test-async-lambda-1',
        InvocationType: 'Event',
        Payload: JSON.stringify(event)
    };

    const function2 = {
        FunctionName: 'dev-test-async-lambda-2',
        InvocationType: 'Event',
        Payload: JSON.stringify(event)
    };
    
    await lambda.invoke(function1).promise();
    await lambda.invoke(function2).promise();

}

        

让我知道我是否可以改善这一点。