こんにちは、CX事業本部 Delivery部の若槻です。
今回は、AWS Lambda関数の同期呼び出しを非同期に行う方法を確認してみました。
やりたいこと
具体的にやりたいことは次の通りです。Lambda関数の挙動をコードでテストするのが目的です。
- Lambda関数を同期的に呼び出し
- 1の2秒後に別の処理を実行
- 1の呼び出しのレスポンスペイロードを取得
1と3の間に2を行いため、1と2の処理を非同期で実行する必要があります。
Promise.all()を使えば良さそう
複数の処理を非同期で実行しつつ実行結果を取得したい場合はPromise.all()
を使うと良さそうです。
Promise.all()
は複数のPromiseオブジェクトを配列で指定し、全てのPromiseが解決できたらそれぞれの戻り値を配列で返します。
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
// Array [3, 42, "foo"]
また「2. 1の2秒後に別の処理を実行」はsetTimeout()
を使うと良さそうです。
setTimeout(code, delay)
やってみた
Lambda関数のハンドラー。(実際のものより簡略化しています)
lib/cdk-sample-app.nyaoFunc.ts
export const handler = async (): Promise<string> => {
await new Promise((r) => setTimeout(r, 5000)); // Sleepを5秒入れて、1と3の間に2を行うようにする
return 'aaa';
};
Lambda呼び出しのレスポンスペイロードを取得するスクリプト。
script.ts
import {
InvocationType,
InvokeCommand,
LambdaClient,
} from '@aws-sdk/client-lambda';
const lambdaClient = new LambdaClient({
region: 'ap-northeast-1',
});
const main = async (): Promise<void> => {
const promiseResults = await Promise.all([
// 1. Lambda関数を同期的に呼び出し
lambdaClient.send(
new InvokeCommand({
FunctionName: 'nyaoFunc',
InvocationType: InvocationType.RequestResponse,
})
),
// 2. 1の2秒後に別の処理(省略)を実行
setTimeout((r) => r, 2000),
]);
const lambdaResponse = promiseResults[0];
// 3. 1の呼び出しのレスポンスペイロードを取得
console.log(Buffer.from(lambdaResponse.Payload!).toString());
};
main();
スクリプトを実行すると、Lambda関数の実行時間5秒を経てレスポンスペイロードを取得できました。
$ time npx ts-node script.ts
"aaa"
npx ts-node script.ts 1.59s user 0.15s system 26% cpu 6.568 total
参考
以上