Jsタスクキューに対する理解


  • この文章は私自身の学習総括であり、非常に詳細ではありません.与えられたリンクを結び付けると、より細かい認識ができます.
  • はまずいくつかの概念を紹介して、分かりやすいです.
    スタックとスタックについて(メモリ領域として)
  • ヒープ(heap):Object、array、functionなどの不確定なメモリサイズのデータを格納する.
  • スタック(stack):基本的なデータタイプを格納し、データタイプを参照してスタック中のデータを指すポインタは、特定のサイズのデータ構造を有し、アクセス速度が速い.
  • コールスタック(コード実行機構として)
  • call stack(コールスタック)とは、機能起動動作のメカニズムを指し、具体的には、リンクを参照する:javascripコールスタック
  • イベントサイクル機構(event loop)
    参考:jsイベントサイクル機構
  • Javascriptスクリプト実行期間
  • が存在します.
  • の役割:ジョブキューの実行可能な関数をコールスタックに押し込む
  • タスクキュー(task queue)
    タスクのキューは主に2種類に分けられます.
  • マクロタスク(macro task):新しい標準ではtaskといいます.
    マクロタスクは主に、script(全体コード)、set Timeout、set Interval、set Immedite、I/O、UI rendengを含む.
  • マイクロタスク(micro task):新しい標準ではjobsといいます.
    マイクロタスクは主にprocess.nextTick,Promise,Object.observe(廃棄),MuttionObserver(html 5新特性)を含む.
  • 以上述べたのはブラウザの方法だけではなく、nodejsの方法もあります.ここでは詳しく説明しません.
    実行の特徴:
  • は、スタックが空であると起動するたびに、イベントサイクル機構は、マクロタスクキュー中のジョブを呼び出しスタックに押し込む.
  • が空のコールスタックを起点とすると、まずすべてのマクロタスクを実行し、その後、すべてのマイクロタスクを実行し、その後、スタックを呼び出してもまた空です.このように一ユニットとして認識され、その後はサイクルで実行されています.
    分解実行プロセス:
  • は、すべての呼び出しスタックにおけるマクロタスク
  • を実行する.
  • マクロタスクの実行中に生成されたマイクロタスクは、マイクロタスクキュー
  • に追加される.
  • マクロタスクを実行した後、すべてのマイクロタスクキューの中のタスク
  • を実行します.
  • 以上の実行が完了し、レンダリングを確認し、GUIスレッドにレンダリングを引き継ぐ
  • .
  • レンダリングが完了したら、jsスレッドは引き継がれ、次のイベントサイクル(scriptは含まない)を開いて、マクロタスクだけを処理します.次のマクロタスク(タスクキューから取る)
  • を実行します.
    理解しにくいところ:
  • 以上のプロセス(マクロタスクまたはマイクロタスクの実行に関わらず)で発生したマクロタスクがマクロタスクキューに入るのを待って、次のループに入ると、
  • は実行されない.
  • しかし、上記の過程で(マイクロタスクを含む)発生したマイクロタスクは、その次のループのマイクロタスクキューの後にすぐに置かれ、
  • が順次実行される.
    上記の2つの句は少し回りくどいかもしれません.上の循環機構のリンクを参考にして、関連する図解があります.
    言い換えると、マイクロタスクは、現在の呼び出しスタックから発生したマクロタスクより優先的に実行される.
    下記のコードの実行過程が理解できれば、タスクキューの実行過程は基本的に理解されるはずです.
    setTimeout(() => {
        console.log('1')
    
        new Promise((resolve) => {
            resolve()
        }).then(() => {
            console.log('2')
        })
    }, 0);
    
    setTimeout(() => {
        console.log('3')
    }, 0);
    
    new Promise((resolve) => {
        resolve()
    }).then(() => {
        console.log('4')
    
        new Promise((resolve) => {
            resolve()
        }).then(() => {
            console.log('5')
        })
    
        setTimeout(() => {
            console.log('6')
        }, 0);
    })
    
    new Promise((resolve) => {
        resolve()
    }).then(() => {
        console.log('7')
    })
    
    //      : 4,7,5,1,2,3,6