0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【javascript】非同期処理/タスクキューとコールスタック

Posted at

#コールスタック

  • 実行中のコードがたどってきたコンテキストの積み重ね。
  • スタックの仕組みを「後入れ先出し」という。
    • 英語:LIFO(Last In, First out)

case


function a() {
}
function b() {
    a();
}
function c() {
    b();
}
c();

上記のケースでどのようにコンテキストが生成され積み重なるのか見てみる。

  • コールスタック(コンテキストの積み重ね。)
    • a関数コンテキスト =>実行中コンテキスト
    • b関数コンテキスト
    • c関数コンテキスト
    • グローバルコンテキスト(関数が呼ばれるまえに生成される。)
  • ※一番上に積み重ねられているのが実行中のコンテキストになる。
  • 実行されたものからcall Stackからなくなっていく。
  • 今回のケースはa()関数が最後に入り、最初に出ていくことになる。
  • すなわち「後入れ先出し」。

※画面右下のCall Stackに注目。

  • anonymousはグローバルコンテキストのこと。
    ezgif.com-gif-maker (2).gif

タスクキュー

  • 実行待ちの非同期処理の行列。
  • 以下のようなキューの仕組みを「先入れ先出し」という。
    • 英語:FIFO(First In, First Out)
    • キューに入ってきたものから処理を進めていく。
タスクE
↓
タスクをキューの中で非同期処理の実行順を管理している。
ーーーーーーーー      
| キュー      |
|   タスクD   |
|   タスクC   |
|   タスクB   |
ーーーーーーーー
↓
タスクA

case


const btn = document.querySelector('button');
btn.addEventListener('click', function task2() {
    console.log('task2 done');
});

function a() {
    setTimeout(function task1() {
        console.log('task1 done');
    }, 4000);

    const startTime = new Date();
    while (new Date() - startTime < 5000);

    console.log('fn a done');
}

a();

上記のコードの説明

  • a関数を実行
    • するとwhile文がメインスレッドを5秒間占有する。
while (new Date() - startTime < 5000);
  • その間にクリックイベントを発火させる。
btn.addEventListener('click', function task2() {
    console.log('task2 done');
  • 5秒後にa関数のfn a done が表示され
  • クリックイベントのtask2 doneが表示され
  • 最後にa関数内のsetTimeoutのtask1 doneが表示される仕組みになっている。

タスクキューとコールスタックの関係はどうなっているのか?

※テキストで読みずらいいと思います。時間がある時に図解にします。

  • 登場人物
    • コールスタック
    • タスクキュー
    • イベントループ
      • イベントループはコールスタックにコンテキストが積まれているかを監視をして、タスクキューに伝えている。
  1. コールスタック
    1. グローバルコンテキストが設置される。
      1. グローバルコンテキストにはのちに実行される非同期処理のクリックイベント(task2)が準備されている。
    2. その後a関数がコンテキストに追加され5秒間メインスレッドを占有する。
      1. a関数にはのちに実行される非同期処理のsetTimeout(task1 done)が準備されている。
  2. イベントループはこの時、「コールスタックは埋まっている」ことをタスクキューに伝えている。
  3. タスクキュー
    1. クリックイベントである、task2 doneをセット
    2. a関数内のsetTimeout(task1 done)をセット
  4. コールスタック
    1. a関数コンテキストが終了しコールスタックから削除
    2. グローバルコンテキストが終了しコールスタックから削除
  5. イベントループ
    1. コールスタックが空になったことをタスクキューに通知
  6. タスクキュー
    1. セットされていた、クリックイベント、setTimeoutを登録した順番でコールスタックにセットする。

ezgif.com-gif-maker (3).gif

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?