JavaScriptでループの中で非同期処理を書く
JavaScriptでループの中で非同期処理を書く:
for文やmap関数の中でasync/awaitを使うときの書き方をメモします。
各非同期処理を逐次的に実行する方法と、非同期的に実行する方法の2つがあります。
awaitを使いたい非同期処理は以下
for文の中で
mapを使います。mapの引数に指定する関数を
1番目の方法は次のループの処理をブロッキングしてしまうので、基本的には2番目の方法を使っておいて、どうしても非同期処理の実行順序を制御したいときのみ1番目の方法を使うのが、性能的な面で良いと思います。
以上
for文やmap関数の中でasync/awaitを使うときの書き方をメモします。
各非同期処理を逐次的に実行する方法と、非同期的に実行する方法の2つがあります。
1. 同期的に実行
2. 非同期的に実行
awaitを使いたい非同期処理は以下
sleep.js
// 引数に指定した秒数だけ待つsleep関数 // Promiseを返す function sleep(second) { return new Promise(resolve => { setTimeout(() => { resolve() }, second * 1000) }) }
1. 同期的に実行する方法
for文の中でawait
を使って書くと、forループの中身を順番に処理してくれるので、同期的に実行してくれます。ここではカウンタを使ったfor文を書いていますが、for .. of
文を使っても同じ挙動になります。syncLoop.js
async function syncLoop() { // 1~5までのランダムな整数の配列を生成 const ram_arr = Array(5).fill(0).map(() => Math.floor(Math.random() * 5 + 1)) // for文を使ってループ処理する for (let i = 0; i < ram_arr.length; i++) { await sleep(ram_arr[i]) // n秒待つ console.log(i+1 + "番目の処理が完了!!" + "待ち時間は" + ram_arr[i] + "秒!!") } console.log("終了!!") } // 実行 // awaitはトップレベルで使うことができない(ES2017時点)ので // asyncをつけた即時関数を作って呼び出している (async ()=>{ console.log("同期的に呼び出す") await syncLoop() }).call()
2. 非同期的に実行する方法
mapを使います。mapの引数に指定する関数をasync
関数にしておくことで、mapの中で呼ばれる処理を非同期に実行しつつ、mapの返り値であるPromise<void>[]
をPromise.all()
関数で待ち受けることで、 すべての処理の完了を待つことができます。asyncLoop.js
async function asyncLoop() { // 1~5までのランダムな整数の配列を生成 const ram_arr = Array(5).fill(0).map(() => Math.floor(Math.random() * 5 + 1)) // mapを使ってループ処理する await Promise.all(ram_arr.map(async (n, i) => { await sleep(n) // n秒待つ console.log(i+1 + "番目の処理が完了!!" + "待ち時間は" + n + "秒!!") return })) console.log("終了!!") } // 実行 // awaitはトップレベルで使うことができない(ES2017時点)ので // asyncをつけた即時関数を作って呼び出している (async ()=>{ console.log("非同期的に呼び出す") await asyncLoop() }).call()
以上
コメント
コメントを投稿