JavaScript 非同期処理 for…of と forEach

結論から言うと、for..ofは非同期処理に対応し、awaitを使うと、順次処理ができる。

forEachは非同期処理には対応しておらず、awaitを使っても、非同期に(ループの順番で)処理が開始される。この時レスポンスは待たない。

並列処理を行いたい場合、ループ処理ではなく、Promise.allを使うのが一般的である。

並列処理は、ループの時とは違い、同時に実行される。

for…of

for...ofループは、反復可能オブジェクト(配列、文字列、マップ、セットなど)を反復処理するために使用される。各反復でオブジェクトの要素が返される。

const array = [10, 20, 30];
for (const value of array) {
    console.log(value); // 10, 20, 30
}

用途: 配列やその他の反復可能なオブジェクトの要素を順次処理するために使用する。

特徴: 反復可能オブジェクトの値を取得する。

for…in

for...inループは、オブジェクトの列挙可能なプロパティを反復処理するために使用される。各反復で、オブジェクトのプロパティ名が返される。

const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
    console.log(key); // a, b, c
}

用途: オブジェクトのプロパティを反復処理するために使用する。

特徴: オブジェクトのプロパティ名を取得する。インデックスが文字列として扱われるので、配列の要素を反復処理するためには推奨されない。

forEach

forEachメソッドは、配列の各要素に対して指定された関数を実行するために使用される。配列のメソッドとして提供され、コールバック関数を引数に取る。

const array = [10, 20, 30];
array.forEach((value) => {
    console.log(value); // 10, 20, 30
});

用途: 配列の各要素に対して関数を実行するために使用する。

特徴: コールバック関数内で同期的に実行される。非同期処理には適していない(非同期関数の中で使うと意図した通りに動作しないことがある)。

for...offorEachの違い

同期/非同期: for...ofawaitを使用して非同期処理を待つことができるが、forEachは非同期処理を正しく待機できない。

配列の範囲: for...ofは配列全体をループするのに適している。forEachも同様だが、forEachは配列のメソッドであるため、配列に対してのみ使用される。

for...ofを使って非同期処理を順次実行

async function processArray(arrData, endPoint) {
    for (const objData of arrData) {
       ~ 何らかの処理 ~
    }
}

// 非同期関数を実行
const arrData = [/* your media objects */];
const endPoint = 'your-endpoint-url';
processArray(arrData, endPoint);

この例では、for...ofループを使って各リクエストを順次実行し、レスポンスを待ってから次のリクエストに進む。

for...inループが配列に対して推奨されない理由

プロパティの順序が保証されない:

  • for...inループは、オブジェクトのプロパティの列挙に適しているため、プロパティの順序が保証されない。配列の要素の順序を保持したい場合には不適切なことがある。

プロトタイプチェーンのプロパティを含む可能性がある:

  • for...inはオブジェクトのすべての列挙可能なプロパティをループする。これにはオブジェクトのプロトタイプチェーン上のプロパティも含まれるため、予期しないプロパティが含まれる可能性がある。

配列の長さや欠落要素を処理しない:

  • 配列の要素のインデックスをループしているわけではないため、欠落している要素(スパースアレイ)も含めて反復処理することになる。

for...inを配列に使用する場合

const array = [10, 20, 30];
array.customProp = 'Hello'; // カスタムプロパティを追加

for (const key in array) {
    console.log(key); // 出力: 0, 1, 2, customProp
    console.log(array[key]); // 出力: 10, 20, 30, Hello
}

このように、for...inはカスタムプロパティも列挙してしまう。

配列に対して推奨される方法

forループ:インデックスを使って配列を反復処理

const array = [10, 20, 30];
for (let i = 0; i < array.length; i++) {
    console.log(array[i]); // 出力: 10, 20, 30
}

for...ofループ:配列の要素を直接反復処理

const array = [10, 20, 30];
for (const value of array) {
    console.log(value); // 出力: 10, 20, 30
}

forEachメソッド:配列の各要素に対して関数を実行

const array = [10, 20, 30];
array.forEach((value) => {
    console.log(value); // 出力: 10, 20, 30
});

結論

  • for...in: オブジェクトのプロパティを列挙するために使用し、配列の反復処理には推奨されない。
  • for...of: 配列やその他の反復可能オブジェクトの要素を反復処理するために使用する。順序が保証される。
  • forEach: 配列の各要素に対して関数を実行するために使用する。非同期処理には適していない。

配列を反復処理する場合、for...offorEachが適している。

配列の順序を保証し、カスタムプロパティを列挙しないため。

タグ: