ホームページ  >  記事  >  ウェブフロントエンド  >  JS ループで await を使用するとどのような「化学反応」が起こるかについて話しましょう

JS ループで await を使用するとどのような「化学反応」が起こるかについて話しましょう

藏色散人
藏色散人転載
2023-03-02 17:22:281690ブラウズ

この記事は、JavaScript ループに関する関連知識を提供します。主に、js ループでの await の使用方法と結果の分析について説明します。興味のある友人は、ぜひ読んでみてください。すべての人に役立つことを願っています。ヘルプ。

序文

この質問はどのようにして生じたのでしょうか?ある日、非同期の知識について学習しているときに、次の質問に遭遇しました。Promise を使用して配列の値を毎秒出力します。

const arr = [1, 2, 3]
arr.reduce((pre, cur) => {
  return pre.then(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(console.log(cur))
      }, 1000);
    })
  })
}, Promise.resolve())

このコードは非常に理解しやすく、

Promise.resolve().then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(1))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(2))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(3))
    }, 1000);
  })
})

と同等です。これを読んで、ループで値を出力するたびに 1 秒停止すれば解決するのではないかと思い、次のコードを思いつきました。

const arr = [1, 2, 3]
const sleep = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
  await sleep(1000)
}

印刷結果も一貫しています。予想通り、私はここで最初の質問をしました: await は async で使用する必要はありませんか?ここだけでどうやって使うことができるのでしょうか? (信じられない場合は、ブラウザのコンソールにコードを入力してみてください)

次に、for を forEach に変更しましたが、効果がまったく達成されていないことがわかりました。 forEach で失敗しますか?

arr.forEach(async item => {
  console.log(item);
  await sleep(1000)
})

これら 2 つの質問から、答えを探して勉強してください。

for ループの await

#async/await を学習していたときに、await は async でのみ使用できるという文があったことを覚えています。実際、この文はそれは何の問題もありません。では、なぜ直接前に await を書くことができるのでしょうか? ブラウザのコンソールに直接書いているからです。エディタでコードを書くときは、非同期の

 <script>  
   const arr = [1, 2, 3]
   const sleep = (ms) => {
     return new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve()
       }, ms)
     })
   }
   const logByOneSecond = async () => {
     for (let i = 0; i < arr.length; i++) {
       console.log(arr[i]);
       await sleep(1000)
     }
   }   
   logByOneSecond()
 </script>

を使用する必要があるので、これは冗談です。(笑) , しかし、理解できないことに遭遇したときは、別の考え方があります。

わかりました。上で述べたように、await はその役割を果たし、JS がプロミスによって処理結果が返されるまで待機してから実行を続行できるようにします。その後、for...of、while も

にすることができます。

const logByForof = async () => {
  for (const item of arr) {
    console.log(item);
    await sleep(1000)
  }    
}
logByForof()
const logByWhile = async () => {
  let i = 0
  while (i !== arr.length) {
    await sleep(1000)
    console.log(arr[i]);
    i++
  }
}
logByWhile()

結果も期待どおりです。ループ内で await を使用すると、効果を達成できます

await in the forEach ループ

As at begin, in forEach には期待される効果はありません; まず第一に、結果が得られます: forEach の async と await は無効です。

私が見た説明は次のとおりです。

  • JavaScript の forEach は Promise の認識をサポートしておらず、async と await もサポートしていないため、 forEach で await を使用することはできません。

  • map/forEach は関数を実行するためにコールバックと組み合わせて内部的に使用されます。await はコールバックの実行を待ちません。

  • forEach はのみサポートします同期コード

2 番目のステートメントは、将来的に疑似コードを次のように簡素化するためのものです。

while(index < arr.length){
  callback(item, index)
}

map/forEach は単純な実行コールバック関数であり、非同期状況は処理されません。 。つまり、map/forEach は同時に複数のコールバック関数を作成します。次のように、複数のコールバック関数が独自の async と await で追加されます

async ()=>{
  await sleep(1000); 
} 
async ()=>{ 
  await sleep(1000);
} 
async ()=>{ 
  await sleep(1000);
}

各関数は互いに独立しており、互いのコールバックは;リクエストは非同期であり、互いに相関関係がないため、順序は保証できません

概要

ループ内での async/await の使用を確認しました通常の for ループの場合、while、for-in、for-of などを含むすべての await はシリアルに呼び出され、安心して使用できますが、forEach、map、filter、reduce などのコールバックを伴う配列メソッドでは、 、などは副作用が多いのでawaitは使わない方が良いです。

[推奨学習:

JavaScript 上級チュートリアル]

以上がJS ループで await を使用するとどのような「化学反応」が起こるかについて話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。