📝
Node.js の Lambda で forEach を使用するときの注意点
Node.js の Lambda 関数ハンドラーの定義 - AWS Lambda
非同期イベントが完了するまでお待ちください。非同期イベントが完了する前に関数が戻る場合、関数が失敗したり、アプリケーションで予期しない動作が発生したりする可能性があります。これは、forEach ループに非同期イベントが含まれている場合に発生します。forEach ループは同期呼び出しを想定しています。
上記の通りです。
実際に試してみました。
試してみた
Node.js 22.x の Lambda 関数を作成、S3 バケットの情報を取得する以下のコードを実行してみました。
index.js
const { S3Client, ListObjectsV2Command } = require("@aws-sdk/client-s3");
const s3 = new S3Client();
exports.handler = async function (event) {
const bucketList = ["bucket-1", "bucket-2", "bucket-3"];
bucketList.forEach(async (bucket) => {
const command = new ListObjectsV2Command({ Bucket: bucket });
const data = await s3.send(command);
console.log(data);
})
return "ok";
};
出力結果は以下の通りで、バケットの情報を出力できていません。
START RequestId: c9d1b30b-f7dd-4bc3-a9e9-1d3b3e55a548 Version: $LATEST
END RequestId: c9d1b30b-f7dd-4bc3-a9e9-1d3b3e55a548
REPORT RequestId: c9d1b30b-f7dd-4bc3-a9e9-1d3b3e55a548 Duration: 851.04 ms Billed Duration: 852 ms Memory Size: 128 MB Max Memory Used: 96 MB Init Duration: 357.33 ms
ドキュメント通りの挙動であることがわかりました。
回避策
【array-foreach-async】forEach()でasync/awaitを使おうとして失敗した皆へ #JavaScript - Qiita
forEach()の代わりにfor〜ofを使用すれば解決できました。
上記ブログに記載の通り、for...of を使用すれば非同期処理の結果を待つことができます。
index.js
const { S3Client, ListObjectsV2Command } = require("@aws-sdk/client-s3");
const s3 = new S3Client();
exports.handler = async function (event) {
const bucketList = ["bucket-1", "bucket-2", "bucket-3"];
for (const bucket of bucketList) {
const command = new ListObjectsV2Command({ Bucket: bucket });
const data = await s3.send(command);
console.log(data);
}
return "ok";
};
出力結果が多いので一部のみ抜粋しますが、バケット情報を取得できました。
'$metadata': {
httpStatusCode: 200,
requestId: 'HVZ1920JJS80R0KP',
extendedRequestId: '5ob6NU0rRulN4QraiNhe1UFtJ56rpH7IMoCT5zLyujG04tVuqHwzl5J25nkREDny9/7L7eY/EsQ=',
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
Contents: [
{
Key: 'favicon.ico',
LastModified: 2022-05-31T00:07:33.000Z,
ETag: '"2dac97e3bdfc1cb44fefed5dbda28664"',
Size: 9662,
StorageClass: 'STANDARD'
},
以下略
まとめ
今回は Node.js の Lambda で forEach を使用するときの注意点を紹介しました。
どなたかの参考になれば幸いです。
Discussion