イベントloop

1951 ワード

javascriptはシングルスレッドです.
タスクのキュー
すべてのタスクは同期タスクと非同期タスクに分けられ、同期タスクはメインスレッド上に整列して実行され、非同期タスクは「タスクキュー」に入る.具体的な実行手順は以下の通りです.
  • すべての同期タスクは、メインスレッド上で実行され、実行スタック
  • を形成する.
  • 非同期タスクが実行結果を得ると、イベント
  • が「タスクキュー」に配置されます.
  • は、まず「実行スタック」の同期タスクを実行し、実行後に「タスクキュー」を読み込み、非同期タスクが終了待ち状態となり、実行スタックに入り実行を開始する.
  • メインスレッドは、前の3ステップ
  • を繰り返します.
    イベントとコールバック関数
    「タスクキュー」はイベントのキューで、先入先のデータ構造です.「タスクキュー」には、IOデバイスのイベントの他に、マウスクリックやページスクロールなどのユーザによって発生するイベントが含まれています.コールバック関数を指定すると、これらのイベントが発生すると「タスクキュー」に入り、メインスレッドの読み込みを待ちます.「コールバック関数」とは、メインスレッドに引っかかるコードのことです.非同期タスクは、コールバック関数を指定しなければなりません.メインスレッドが非同期タスクを実行し始めると、対応するコールバック関数が実行されます.
    イベントループ
    メインスレッドが「タスク待ち行列」からイベントを読み込みます.このプロセスはループが継続しているため、全体のこのような運行メカニズムは、Event Loop(イベントサイクル)とも呼ばれます.
    タイマー
    非同期タスクを置くイベント以外に、タイミングイベントを「タスクキュー」に置くこともできます.タイマー機能は主にsetTimeout()とsetInterval()の2つの関数によって完成されています.それらの内部運行メカニズムは完全に同じです.前者が指定したコードは1回で実行され、後者は繰り返し実行されます.以下は主にsetTimeout()について説明する.
    console.log(1);
    setTimeout(function(){console.log(2);},1000);
    console.log(3);
    
    上のコードの実行結果は、setTimeout()が2行目を1000ミリ秒後に実行するため、1,3,2である.
    setTimeout()の2番目のパラメータを0にすると、現在のコードの実行が完了した(実行スタックがクリアされた)後、直ちに(0ミリ秒間隔)で指定されたコールバック関数が実行されることを表します.
    setTimeout(function(){console.log(1);}, 0);
    console.log(2);
    
    上のコードの実行結果は常に2,1であり、2行目を実行した後だけ、システムは「タスクキュー」のコールバック関数を実行します.つまり、setTimeout(fn,0)は、あるタスクがメインスレッドで最も早い空き時間で実行されるように指定されています.つまり、できるだけ早く実行してください.これは「タスクキュー」の末尾にイベントを追加しますので、同期タスクと「タスクキュー」の既存のイベントが全部処理されてから実行されます.したがって、プロミセとセットTimeoutの両方は常にプロミセが先に実行されます.HTML 5標準は、setTimeout()の2番目のパラメータの最小値(最短間隔)を規定しており、4ミリ秒以下であってはいけません.この値を下回ると自動的に増加します.これに先立ち、古いバージョンのブラウザは最短間隔を10ミリ秒に設定します.また、これらのDOMの変動(特にページ再レンダリングに関する部分)については、通常すぐに実行されず、16ミリ秒ごとに実行される.この場合はrequest Animation Frame()を使うとsetTimeout()より効果がいいです.なお、setTimeout()は、イベントを「タスクキュー」に挿入するだけで、現在のコード(実行スタック)が実行されるまでは、メインストリームは、指定されたコールバック関数を実行することができます.現在のコードが長くかかると、長く待たなければならないかもしれませんので、保証できません.コールバック関数は必ずsetTimeout()で指定された時間に実行されます.