参考: JS_js 非同期ループでシーケンスをループして非同期操作を実行する方法 - CSDN ブログ
JS ループトラバーサルでの非同期の使用
非同期操作を同期順序で実行するには、各非同期操作をループで順番に実行する必要があります。
1. の場合forEach
(使用には注意してください)
forEach
メソッドはsynchronousです。つまり、forEach
コールバック関数が同期的に呼び出され、forEach
コールバックで非同期操作が実行されます。各トラバーサルで実行されるこれらの非同期操作は並列に実行されます。その各反復は、前の反復が完了した直後に実行されます。したがって、実行フローがブロックされ、非同期操作の完了順序が保証されないため、forEach で非同期操作を使用することはできません。
//定义一个异步函数
const foo1 = (i:any)=>{
return new Promise((resolve, reject) => {
setTimeout(() =>{
console.log(i);
resolve(i)
},1000)
})
}
const arr = [1,2,3,4,5]
const b = () =>{
arr.forEach(async e => {
console.log(e);
await foo1(e)
});
}
b(); // 1 2 3 4 5 1 2 3 4 5
2. forfor
ループ (非推奨)
for
このメソッドは非同期です。つまり、各ループは非同期操作を順番に実行できます。
欠点: 各ループのスコープは 1 つであるため、非同期操作が終了する前に次の反復に入る可能性があります。
//定义一个异步函数
const foo1 = (i:any)=>{
return new Promise((resolve, reject) => {
setTimeout(() =>{
console.log(i);
resolve(i)
},1000)
})
}
const arr = [1,2,3,4,5]
async function a() {
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
await foo1(arr[i])
}
}
a() // 输出:1 1 2 2 3 3 4 4 5 5
3. for of ループの場合 (推奨)
これは、配列、マップ、セットなどの反復可能なオブジェクトを走査するために ES6 で導入された新しいループ インターフェイスです。非同期操作を使用する場合、for...of ループが最も推奨される方法です。反復ごとに新しいスコープが作成され、非同期操作の独立性と安全性が確保されます。
次の反復に入る前に、非同期実行が終了するのを待つことができます。
async function processData(data) {
for (const item of data) {
await doAsyncOperation(item);
}
}
async function doAsyncOperation(item) {
return new Promise((resolve, reject) => {
// 异步操作代码
});
}
この例では、processData
関数は for...of
ループを使用してデータを反復処理し、反復ごとに非同期操作が完了するのを待ちます。 関数は完了を待つことができるように doAsyncOperation
1 を返します 。このようにして、非同期操作の実行順序が保証されます。Promise
processData
4. Promise.all を使用して、
async function processData(data) {
const promises = data.map(doAsyncOperation);
await Promise.all(promises);
}
async function doAsyncOperation(item) {
return new Promise((resolve, reject) => {
// 异步操作代码
});
}
この例では、processData
関数は map
メソッド を使用してPromise
すべての非同期操作を含む配列を作成し、その配列に対してメソッドを呼び出します Promise.all
。Promise.all
このメソッドは、すべての非同期操作が完了するまで待機し、その結果を配列として返します。このようにして、すべての非同期操作が並行して実行されます。
概要: したがって、ループ内で非同期操作を呼び出す必要がある場合は、forEach (同期) を慎重に使用してください。For ループは推奨されません (各反復は同じスコープ内にあります)。for of および Promise.all を使用することをお勧めします。