イベントloop jsイベントサイクルmicrotask macrotask

4162 ワード

面接の問題を置いて、れんがを投げます.
console.log('start')

const interval = setInterval(() => {  
  console.log('setInterval')
}, 0)

setTimeout(() => {  
  console.log('setTimeout 1')
  Promise.resolve()
      .then(() => {
        console.log('promise 3')
      })
      .then(() => {
        console.log('promise 4')
      })
      .then(() => {
        setTimeout(() => {
          console.log('setTimeout 2')
          Promise.resolve()
              .then(() => {
                console.log('promise 5')
              })
              .then(() => {
                console.log('promise 6')
              })
              .then(() => {
                clearInterval(interval)
              })
        }, 0)
      })
}, 0)

Promise.resolve()
    .then(() => {  
        console.log('promise 1')
    })
    .then(() => {
        console.log('promise 2')
    })
急いで答えを発表しないで、まず分析します.
まず知っています
jsは単スレッド言語です.
つまり一回で一つのことしかできないということです.
多くのサイトでは大量計算が不要で、プログラムにかかる時間は主にディスクI/OとネットワークI/Oに集中しています.
SSDの読み取りは速いですが、CPUのコマンド処理速度と比べても1桁以上ではなく、ネットワーク上のパケットの往復時間がもっと遅いです.(ゲームの遅延に注意しましたか?)
so:いくつかのcpuが直接実行するタスクは、優先的にメインラインのタスクを実行し、その後、ioがデータを返す必要があるタスクは、実行されるのを待つタスクになります.
したがって、同期タスク(synchronous)と非同期タスク(asynchronous)があります.
同期タスク:
メインスレッド上に並んで実行したタスクは、前のタスクが実行された後、次のタスクが実行されます.
非同期タスク:
メインスレッドに入らず、「タスクキュー」(task queue)に入るタスクは、「タスクキュー」がメインスレッドに通知し、ある非同期タスクが実行できます.このタスクはメインスレッドに入ります.
つまり:
メインラインが空になったら、「ジョブキュー」を読みに行きます.これはJavaScriptの運行メカニズムです.
Microtask Macrotask
ミッションチームは一つだけではなく、microtasksとmacrotasksがあります.
microtasks:
  • process.nextTick
  • promise
  • Object.observe
  • MuttionObserver
  • macrotasks:
  • setTimeout
  • set Interval
  • set Immedite
  • I/O
  • UIレンダリング
  • whatwg仕様:https://html.spec.whatwg.org/multipage/webappapis.html#task-queue
  • イベントサイクルは一つ以上のタスクキュー
  • task queueはmacrotask queue
  • 各イベントごとにmicrotask queue
  • task queue==macrotask queue!microtask queue
  • 1つのタスクtaskは、macrotask queueに入れてもいいし、microtask queueに入れてもいいです.
  • これらの定義を理解したら、実行原理を見ます.
    イベントサイクルの順序は、JavaScriptコードの実行順序を決定します.それはscript(全体コード)から初めて循環します.その後、グローバルコンテキストは関数コールスタックに入ります.スタックがクリアされるまで(全体の部分のみ)、すべてのmicro-taskを実行します.すべての実行可能なmicro-taskが実行された後.サイクルは再びmacro-taskから始まり、その中の一つのタスクキューを見つけて実行しました.そして、すべてのmicro-taskを実行して、このようにずっと循環していきます.
    もっと注意してください.
    ScrotaskはScriptタグに包まれているjsコードもtaskです.
    ですから、最初の問題の答えは次の通りです.
    start promise 1 promise 2 set Interval set Timeout 1 promise 4 set Interval set Timeout 2 promise 6
    簡単に言えば、全体のjsコードのこのmacrotaskは先に実行して、同期コードの実行が終わった後にmicrotaskがmicrotaskを実行することがいて、microtaskがなくて、次のmacrotaskを実行して、このように繰り返して終わりになります.