起きている問題
for文の処理が重く、メモリ不足が発生。
注意
以下の処理は説明のため簡単なものに置き換えています。実際にはこの程度の処理ではメモリアウトは起こりません。
私の場合はSendGridのメール送信でメモリアウトが起きました。
・JavaScript
1 2 3 4 5 6 7 |
console.log("start"); for (let i = 0; i < 5; i++) { setTimeout(() => { console.log('i =', i); }, 1000); } console.log("end"); |
・ログ
1 2 3 4 5 6 7 |
start end //この時点では、for文内の非同期処理が5件たまっている状態 i = 0 i = 1 i = 2 i = 3 i = 4 |
・エラーコード …out of memoryとあり、メモリ不足に陥っている
1 2 |
Cannot get stack trace in GC. FATAL ERROR: SequentialMarkingDeque::EnsureCommitted Allocation failed - process out of memory |
やりたいこと
for文内で非同期処理をすると、処理が渋滞してしまう。この状態だとメモリ不足などの問題を引き起こす場合がある。
1ループの処理を全て終えた上で次のループに進むようにしたい。
・想定ログ
1 2 3 4 5 6 7 |
start i = 0 i = 1 i = 2 i = 3 i = 4 end |
やり方
async関数とPromiseを使う
・JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
(async () => { console.log("start"); for (let i = 0; i < 5; i++) { await promise(i); } console.log("end"); }).call() function promise(i) { return new Promise(resolve => { setTimeout(() => { console.log('i =', i); resolve() }, 1000) }) } |
・ログ
1 2 3 4 5 6 7 |
start i = 0 i = 1 i = 2 i = 3 i = 4 end |
同期処理は大変かつ大切ですね…