LoginSignup
32
19

More than 3 years have passed since last update.

【JavaScript】forループ内でawaitする方法

Last updated at Posted at 2020-05-29

経緯

forループ内で同期処理を行いたかったので調べてみたら for await...of というものがあることを知りました。

結論

このように async のなかに for await...of を書くことで forループ内で await を宣言できます。

index.js
// 対象の反復オブジェクト
const targetArr = [1, 2, 3];

// 実行する関数
const sampleFunc = (value) => {
// asyncの効果は各functionブロックで切れるので逐一指定が必要
    return new Promise(resolve => { 
        // 2秒待ってから計算結果をresolveする
        setTimeout(() => {
            console.log('Calculating...');
            resolve(value * 2);
        }, 2000);
    })
}

// for await...of文は必ずasyncの中で
(async () => {
  for await (num of targetArr) {
    // 関数の実行結果を格納して表示
    const result = await sampleFunc(num);
    console.log(result);
  }
})();

for await...of とは

for await...of 文は非同期(と同期)の反復オブジェクトを繰り返して処理するループを作ります。対象の反復オブジェクトは、ビルトインの String、Array、配列様オブジェクト( arguments、NodeList 等)、TypedArray、Map、Set、さらに、ユーザーが定義した非同期・同期の反復オブジェクトが含まれます。オブジェクトの各プロパティの値に対して実行されるステートメントを使用してカスタム反復フックを呼び出します。

簡単に言うと
反復オブジェクト(ArrayやObjectなど)の中で同期処理を行う事ができる文です。

ESLintでは非推奨

便利な構文ですが、ESLintでは設計思想的な意味で推奨されていません。

https://eslint.org/docs/rules/no-await-in-loop

Performing an operation on each element of an iterable is a common task. However, performing an await as part of each operation is an indication that the program is not taking full advantage of the parallelization benefits of async/await.
Usually, the code should be refactored to create all the promises at once, then get access to the results using Promise.all(). Otherwise, each successive operation will not start until the previous one has completed.
Concretely, the following function should be refactored as shown:

反復の各要素に対して操作を行うことは一般的な作業です。
しかしながら、各段階の操作で await を実行すると async/await による並列化の利点を十分に活用できません。
一般にこのようなコードは、全てのプロミスを一度に作成し Promise.all() を用いて結果を得るようにするべきです。

32
19
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
19