国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關于瀏覽器Event Loop

youkede / 3270人閱讀

摘要:的宿主最開始本身就是瀏覽器,處理用戶的交互事件。既然是單線程的,那就意味著任務需要排隊,只有前一個任務執行完畢,下一個任務才能開始,于是就有了任務隊列。事件循環有兩種用于瀏覽上下文的事件循環和用于的事件循環。

最近看到Event Loop這個詞出現的頻率有點高,于是查閱各方資料在此記錄一下。

先不說概念,我們來看段代碼:

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

Promise.resolve().then(function() {
  console.log("promise1");
}).then(function() {
  console.log("promise2");
});

console.log("script end");

復制這段代碼到控制臺,在Chrome會輸出如下結果

Why?

如果想弄清楚原因,就必須得弄清楚今天要提到的概念Event Loop。

運行時概念

函數調用形成了一個棧幀。

function foo(b) {
  var a = 10;
  return a + b + 11;
}

function bar(x) {
  var y = 3;
  return foo(x * y);
}

console.log(bar(7)); // 返回 42

當調用 bar 時,創建了第一個幀 ,幀中包含了 bar 的參數和局部變量。當 bar 調用 foo 時,第二個幀就被創建,并被壓到第一個幀之上,幀中包含了 foo 的參數和局部變量。當 foo 返回時,最上層的幀就被彈出棧(剩下 bar 函數的調用幀 )。當 bar 返回的時候,棧就空了。

對象被分配在一個堆中,即用以表示一大塊非結構化的內存區域。

隊列

一個 JavaScript 運行時包含了一個待處理的消息隊列。每一個消息都關聯著一個用以處理這個消息的函數。

在事件循環期間的某個時刻,運行時從最先進入隊列的消息開始處理隊列中的消息。為此,這個消息會被移出隊列,并作為輸入參數調用與之關聯的函數。正如前面所提到的,調用一個函數總是會為其創造一個新的棧幀。

函數的處理會一直進行到執行棧再次為空為止;然后事件循環將會處理隊列中的下一個消息(如果還有的話)。

為什么JavaScript是單線程

稍理解JavaScript的都知道JavaScript是單線程,即同一時間只能處理一件事情。JavaScript為什么不能是多線程呢,這樣就可以同時處理多件事情提高效率。
JavaScript的宿主最開始本身就是瀏覽器,處理用戶的交互事件。作為瀏覽器腳本,它只能一次做一件事情,假如用戶點擊一個按鈕的時候,需要刪除一個節點,而另一段代碼此時又要添加這個節點,那JavaScript該如何處理,以誰為準?
所以JavaScript在創造之初就考慮到了這點,也決定了它只能是單線程,這是它的核心特征之一。

Event Loop

既然JavaScript是單線程的,那就意味著任務需要排隊,只有前一個任務執行完畢,下一個任務才能開始,于是就有了任務隊列。如果一個任務耗時很長,下面的任務就得一直等著,明顯不太合理,那么能否先把耗時很久的任務先掛起來,先執行后面的任務,等IO設備返回的結果,再去執行之前掛著的任務。

于是任務就可以分兩種:同步任務和異步任務

同步任務指的是,在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務;異步任務指的是,不進入主線程、而進入"任務隊列"(task queue)的任務,只有"任務隊列"通知主線程,某個異步任務可以執行了,該任務才會進入主線程執行。

(1)所有同步任務都在主線程上執行,形成一個執行棧(execution context stack)。
(2)主線程之外,還存在一個"任務隊列"(task queue)。只要異步任務有了運行結果,就在"任務隊列"之中放置一個事件。
(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務隊列",看看里面有哪些事件。那些對應的異步任務,于是結束等待狀態,進入執行棧,開始執行。
(4)主線程不斷重復上面的第三步。

異步任務指的是異步的代碼加入到任務隊列中,等待主線程通知執行
Event Loop

主線程從"任務隊列"中讀取事件,這個過程是循環不斷的,所以整個的這種運行機制又稱為Event Loop!

Event loop:客戶端必須使用本章節中所描述的事件循環,來協調事件,用戶交互,腳本,呈現,網絡等等。 事件循環有兩種:用于瀏覽上下文的事件循環和用于 worker 的事件循環。

任務隊列分為宏任務隊列(macro tasks) 和 微任務隊列(micro tasks)

如何判斷一段代碼是加入到宏任務隊列還是微任務隊列?
每個任務都由特殊任務源來定義。 來自同一個特殊任務源的所有任務都將發往特定事件循環。所以我們可以按照不同的來源進行分類,不同來源的任務都對應到不同的任務隊列中

(macro-task 宏任務)來源:I/O, setTimeout + setInterval + setImmediate, UI renderder ···
(micro-task 微任務)來源:Promise ,process.nextTick ,MutationObserver, Object.observe ···
Microtasks are usually scheduled for things that should happen straight after the currently executing script, such as reacting to a batch of actions, or to make something async without taking the penalty of a whole new task. The microtask queue is processed after callbacks as long as no other JavaScript is mid-execution, and at the end of each task. Any additional microtasks queued during microtasks are added to the end of the queue and also processed. Microtasks include mutation observer callbacks, and as in the above example, promise callbacks.

看下完整的執行過程:

? 代碼開始執行,JavaScript 引擎對所有的代碼進行區分。
? 同步代碼被壓入棧中,異步代碼根據不同來源加入到宏任務隊列尾部,或者微任務隊列的尾部。
? 等待棧中的代碼被執行完畢,此時通知任務隊列,執行位于隊列首部的宏任務。
? 宏任務執行完畢,開始執行其關聯的微任務。
? 關聯的微任務執行完畢,繼續執行下一個宏任務,直到任務隊列中所有宏任務被執行完畢。
?執行下一個任務隊列。

參考文檔:

并發模型與事件循環

JavaScript 運行機制詳解:再談Event Loop

什么是瀏覽器的事件循環(Event Loop)?

從 薛定諤的貓 聊到 Event loop

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103302.html

相關文章

  • 初窺JavaScript事件機制的實現(一)—— Node.js事件驅動實現概覽

    摘要:如果當前沒有事件也沒有定時器事件,則返回。相關資料關于的架構及設計思路的事件討論了使用線程池異步運行代碼。下一篇初窺事件機制的實現二中定時器的實現 在瀏覽器中,事件作為一個極為重要的機制,給予JavaScript響應用戶操作與DOM變化的能力;在Node.js中,事件驅動模型則是其高并發能力的基礎。 學習JavaScript也需要了解它的運行平臺,為了更好的理解JavaScript的事...

    lavor 評論0 收藏0
  • Event Loop - JS執行機制

    摘要:心塞塞根據規范,事件循環是通過任務隊列的機制來進行協調的。等便是任務源,而進入任務隊列的是他們指定的具體執行任務回調函數。然后當前本輪的結束,主線程可以繼續取下一個執行。 依然是:經濟基礎決定上層建筑。 說明 首先,旨在搞清常用的同步異步執行機制 其次,暫時不討論node.js的Event Loop執行機制,以下關于瀏覽器的Event Loop執行機制 最后,借鑒了很多前輩的研究文...

    muddyway 評論0 收藏0
  • 事件循環機制(event loop

    摘要:了解事件循環機制有助于理解的執行過程,同時這也是面試常見題。那么這個回調函數將在何時由誰執行呢已知是瀏覽器環境提供的,因此瀏覽器將對它進行處理,瀏覽器會在本次事件完成,即計時結束后,將回調函數加入循環隊列中,然后等待被加入執行棧執行。 如果有人問JavaScript是什么,也許你會說它是一個單線程、非阻塞、異步、解釋型的腳本語言。那么作為一個單線程語言,它是怎么實現非阻塞、異步的?這就...

    tain335 評論0 收藏0
  • Event Loop 其實也就這點事

    摘要:眾所周知,是,也就意味著在執行的過程中,是,而這樣的特性,正是由一個叫的東西決定的有且僅有一個。無論從工程效率還是用戶體驗的角度來說,這都是不被允許的一件事情。五秒后,結束計時,將回調函數下放到中。至此,正式引出的概念。 前段時間在網上陸續看了很多關于 Event loop 的文章,看完也就混個眼熟,可能內心深處對這種偏原理的知識有一些抵觸心情,看完后也都沒有去深入理解。最近在看 Vu...

    PrototypeZ 評論0 收藏0
  • script標簽與event loop在W3C規范及覽器中的表現

    摘要:瀏覽器推遲事件直到所有的腳本都處于狀態。解析器將處理執行這個腳本。創建這個腳本的解析器的文檔有正在阻塞腳本執行腳本元素為等待解析阻塞的腳本的狀態,同一時刻只能有一個這樣的腳本存在。解析器將一個或多個字符轉換為表并處理,這個過程是一個典型的。 前言 本文主要對W3C規范中關于script標簽和event loop相關的篇幅做了簡單的探討,針對一些必要的相關概念進行了適當的標注和說明。雖然...

    codergarden 評論0 收藏0

發表評論

0條評論

youkede

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<