JavaScriptのハード部分のマスタリング:非同期性I


イベントループ


JavaScriptの非同期性を理解するには1つの基本概念を理解する必要があります:JSエンジンは次に何を実行するか?これは、この質問に答える方法の非常に簡単な概要です.
JavaScriptは(ほとんどの場合)単一スレッドのため、JavaScriptのすべてが同期している場合は、JSエンジンは、ソースコードに表示されるように、すべてのステートメントを1つずつ実行し、実行を終了し、次の行に移動します.
しかし、それはウェブ開発に関して信じられないほど制限されます.この問題を解決するには、ブラウザ/ノードのAPIがあります.JS提供は非同期で、基本的にはJSエンジンが最初に実行されたときに実行しないことを意味します.代わりに、すべての同期ステートメントが終了したら、実行されるキューに入れます.考えましょう
function printHello() {
  console.log("Hello");
}
setTimeout(printHello, 0);
console.log("Me first!");
だってsetTimeout が実行されるprintHello 0ミリ秒では、出力は以下のようになります.
Hello
Me first!
しかし実際には出力は
Me first!
Hello
これはsettimeoutが非同期API(callback関数)であるため、実行は“task queue”に格納されます.すべての同期コードが既に実行された後に、タスクキュー内のすべてが実行されます.
注意:console.log 実際には非同期関数であるが、その詳細についてはシンプルで明確なデモンストレーションのために、その詳細を詳しく調べている.

約束する


ES 6で導入された約束は、1つの追加キューをミックスに追加します.考慮:
function display(data){console.log(data)}
function printHello(){console.log("Hello");}
function blockForLong(){
    const arr = [];
    for (let i = 0; i < 3_000_000_000; i++>){
        arr.push(i)
    }
 }
setTimeout(printHello, 0);
const futureData = fetch('https://twitter.com/AmeriRyan/status/1291935897076641792')
futureData.then(display)
blockForLong()
console.log("Me first!");
このコードは正確にfetch ()がどのように動作するかではなく、正しく動作しませんが、単純性のためにfetch URLを文字列として受け取り、約束を返す関数です.blockForLong は、目的に重要なことは何もしないが、実行するのに長い時間を要する同期関数である.ファーストコールsetTimeout その実行printHello 0ミリ秒で.その後、我々は約束を処理し、関数に渡すdisplay コンソールに出力するだけです.次に実行しますblockForLong そして最後にconsole.log . 何が最初に印刷されるか推測できますか.
まず、すべての同期コードを実行する.その意味blockForLong が最初に呼び出され、Me first! がコンソールに出力される.コールバック関数が置かれる「タスク待ち行列」の上に優先権がある「Microtask Queue」と呼ばれる待ち行列に、約束は置かれます.たとえそうだとしてもsetTimeout ソースコードで最初に表示されますdisplay 関数を返します.printHello 関数ラスト.
したがって、JavaScriptのイベントループは次のようになります.
  • 同期符号
  • Micro Task Queueの何か(約束)
  • task queue (コールバック関数)の何か
  • この例の実行順序に従うことができるならば、あなたはすべての今後のエクササイズ(多分MDNから少しの援助で)を解決することができなければなりません.
    次のセクションでは、我々は約束に私たちを紹介するだけでなく、非同期性をマスターする必要があります10演習を練習します.