JavaScriptにおけるイベントループ動作の原理
この文章はhttps://meetup.toast.com/posts/89を参考に整理したものです.
@この文書では、ブラウザ内のイベントループについてのみ説明します.
コールスタック
jsが実行する関数の順序を含むスタック
呼び出しスタックを使用します.
これがjsが単一呼び出しスタックと呼ばれる理由である.
(ES 6から少し変わってきましたが、まずはこのように理解しておきます)
タスクキュー
コールバック関数待機キュー
特定の条件が満たされている場合は、キューにコールバック関数を追加します.
jsエンジンの外部に存在する
イベントループ
呼び出しスタックが空になるたびに、テクニカルキューからコールバック関数が取り出され、実行されます.
jsエンジンの外部に存在する
ブラウザタイマ(Web APIに含む)
時間を計る.
すべての非同期APIは、タスク(または条件)が完了した後、技術キューにコールバック関数を追加する. イベントループは、「現在実行されていないタスクの場合」(主に呼び出しスタックが空の場合)に、タスクキュー内の最初のタスクを取り出し、呼び出しスタック上に配置して実行します. ex)settimeout(addEventListenerも同様) web APIのtimerは、特定の時間に技術キューにコールバック関数を追加する. jsエンジンのコールスタックが空であることを確認し、空である場合、テクノロジーキューからテクノロジーを取り出し、コールスタックにアップロードします. コールスタックで を順次実行する.
ブラウザはサーバの応答を受信し、(B)を技術キューに追加し、呼び出しスタックが空の場合、イベントループが実行される(B).
しかし、問題は(B)が(A)のコンテキスト内にいないことだ.したがって(B)はtry catchの影響を受けない.
0はすぐには意味しません.
ただし、longTakingProcess()と以下の関数は呼び出しスタックに残っているため、showResult()が実行された後にのみロードメッセージレンダリング関数が呼び出されます.
このような問題を防止するために、
次は解決コードです
マイクロテクノロジーは一般的な技術より優先度の高い技術と言える.
マイクロテクノロジーは一般的なテクノロジーライブラリに格納されず、単独でマイクロテクノロジーライブラリに格納されます.
次のコードを見て
Promiseのthen()メソッドは、コールバックをマイクロテクノロジーキューに格納します.したがって
マイクロテクノロジー:B、C
技術ヒント:A
すなわち,このように保存してB−>C−>Aの順に運転する.
@この文書では、ブラウザ内のイベントループについてのみ説明します.
🎡 イベントループ構造
コールスタック
jsが実行する関数の順序を含むスタック
呼び出しスタックを使用します.
これがjsが単一呼び出しスタックと呼ばれる理由である.
(ES 6から少し変わってきましたが、まずはこのように理解しておきます)
タスクキュー
コールバック関数待機キュー
特定の条件が満たされている場合は、キューにコールバック関数を追加します.
jsエンジンの外部に存在する
イベントループ
呼び出しスタックが空になるたびに、テクニカルキューからコールバック関数が取り出され、実行されます.
jsエンジンの外部に存在する
//내부적으로 이렇게 동작한다고 한다.
while(queue.waitForMessage()){
queue.processNextMessage();
}
ブラウザタイマ(Web APIに含む)
時間を計る.
🧶 非同期イベントの操作順序
😅 非同期APIでのtry catchの問題
$('.btn').click(function() { // (A)
try {
//서버의 응답을 요청하는 코드인듯
$.getJSON('/api/members', function (res) { // (B)
// 에러 발생 코드
});
} catch (e) {
console.log('Error : ' + e.message);
}
});
次のコードはtry catchでスナップできませんブラウザはサーバの応答を受信し、(B)を技術キューに追加し、呼び出しスタックが空の場合、イベントループが実行される(B).
しかし、問題は(B)が(A)のコンテキスト内にいないことだ.したがって(B)はtry catchの影響を受けない.
🤨 settimeout(fn,0)はすぐに実行することを意味しますか?
0はすぐには意味しません.
$('.btn').click(function() {
showWaitingMessage(); // 비동기 함수, 로딩메세지를 보여주는 함수
longTakingProcess();
hideWaitingMessage();
showResult();
});
まず、showWattingMessage()のレンダリングエンジンは、レンダリング関数をテクニカルキューに送信します.ただし、longTakingProcess()と以下の関数は呼び出しスタックに残っているため、showResult()が実行された後にのみロードメッセージレンダリング関数が呼び出されます.
このような問題を防止するために、
setTimeout(fn, 0)
が使用される.次は解決コードです
$('.btn').click(function() {
showWaitingMessage(); // 비동기 함수, 로딩메세지를 보여주는 함수
setTimeout(function() {
longTakingProcess();
hideWaitingMessage();
showResult();
}, 0);
});
😱 マイクロテクノロジー?
マイクロテクノロジーは一般的な技術より優先度の高い技術と言える.
マイクロテクノロジーは一般的なテクノロジーライブラリに格納されず、単独でマイクロテクノロジーライブラリに格納されます.
次のコードを見て
setTimeout(function() { // (A)
console.log('A');
}, 0);
Promise.resolve().then(function() { // (B)
console.log('B');
}).then(function() { // (C)
console.log('C');
});
このコードの実行順序はB->C->Aである.Promiseのthen()メソッドは、コールバックをマイクロテクノロジーキューに格納します.したがって
マイクロテクノロジー:B、C
技術ヒント:A
すなわち,このように保存してB−>C−>Aの順に運転する.
Reference
この問題について(JavaScriptにおけるイベントループ動作の原理), 我々は、より多くの情報をここで見つけました https://velog.io/@0307kwon/javascript의-이벤트루프-동작원리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol