別のラムダからawsラムダを非同期で呼び出す必要があります。同期呼び出しの作業コードがあります。
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');
}
それはメッセージを正しく返します。しかし、私の 'testLambda'関数は呼び出されません(テストラムダのクラウド監視ログは生成されません)。このコードに関連する問題は何ですか。
Lambda invoke()のドキュメント に従って、デフォルトでLambda関数がRequestResponse
呼び出しタイプを使用して呼び出されることがわかります。関数を非同期で呼び出すには、次のようにEvent
呼び出しタイプを指定する必要があります。
lambda.invoke({
FunctionName: 'testLambda',
InvocationType: 'Event',
Payload: JSON.stringify(event, null, 2)
},function(err,data){});
AWS Lambdaで現在最新の node.js 8.1 バージョンを使用していました。
2番目のラムダは、使用するまで実行されませんでした(そして、コールバック関数は呼び出されませんでした)。 非同期/待機 機構。
したがって、ハンドラー関数は非同期である必要があり、 '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();
};
ハンドラーは、2番目のラムダが終了するのを待たないことに注意してください。トリガーされ、コールバック関数が呼び出されるだけです。
ハンドラー内からPromiseを返すこともできます。2番目の関数でawaitを使用する必要はありません。
Promiseとasync/awaitを使用する場合、以下を除いてインポートは必要ありません。
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();
それが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);
}));
上記と同様の解決策が必要でした。 lambda.invoke
で複数のラムダ関数を使用する場合、ステップ関数が推奨されますが、次のコードスニペットを使用して、ベースのラムダ関数から他の2つのラムダ関数を非同期的に呼び出します。
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();
}
これをより効率的に改善できるか、それとも有用かを教えてください。