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

資訊專欄INFORMATION COLUMN

JavaScript Event loop 事件循環

luckyyulin / 2488人閱讀

摘要:階段有兩個主要功能也會執行時間定時器到達期望時間的回調函數執行事件循環列表里的函數當進入階段并且沒有其余的定時器,那么如果事件循環列表不為空,則迭代同步的執行隊列中的函數。如果沒有,則等待回調函數進入隊列并立即執行。

Event Loop

本文以 Node.js 為例,講解 Event Loop 在 Node.js 的實現,原文,JavaScript 中的實現大同小異。

什么是 Event Loop ?

單線程的 Node.js 能夠實現無阻塞IO的原因就是事件循環(Event Loop)。

現在大多數系統內核是多線程的,所以它們可以在后臺執行多個操作,當這些操作完成時,內核就會通知 Node.js,而這些操作的回調函數被添加到事件輪詢列表(poll queue),并且 Node.js 會在適當的時機執行回調函數。

概覽 Event Loop

當 Node.js 開始執行時,便初始化 Event Loop,執行過程中會存在許多異步操作,如:REPL、定時器(timers)、調用異步 API(請求,事件監聽),在主進程代碼執行完后,便開始運行 Event Loop

下圖描述了 Event Loop 中的各個階段

   ┌───────────────────────┐
┌─>│        timers         │ 這個階段執行 `setTimeout()` 和 `setInterval()` 中的回調函數
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     │ 這個階段執行除了 `close` 回調函數以外的幾乎所有的 I/0 回調函數
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │ 這個階段僅僅 Node.js 內部使用
│  └──────────┬────────────┘      ┌───────────────┐
│  ┌──────────┴────────────┐      │   incoming:   │
│  │         poll          │<─────┤  connections, │ 執行隊列中的回調函數、檢索新的回調函數
│  └──────────┬────────────┘      │   data, etc.  │
│  ┌──────────┴────────────┐      └───────────────┘
│  │        check          │ `setImmediate()` 將在這里被調用
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    │ `close` 回調函數被調用如:socket.on("close", ...)
   └───────────────────────┘
詳解 Event Loop 的各個階段
timers

setTimeout() 和 setInterval() 都要指定一個運行時間,這個運行時間其實不是確切的運行時間,而是一個期望時間,Event Loop 會在 timers 階段執行超過期望時間的定時器回調函數,但由于你不確定在其他階段甚至主進程中的事件執行時間,所以定時器不一定會按時執行。

var asyncApi = function (callback) {
  setTimeout(callback, 90)
}

const timeoutScheduled = Date.now();
setTimeout(() => {
  const delay = Date.now() - timeoutScheduled;
  console.log(`${delay}ms setTimeout 被執行`); // 140ms 之后被執行
}, 100);

asyncApi(() => {
  const startCallback = Date.now();
  while (Date.now() - startCallback < 50) {
    // do nothing
  }
})
I/O callbacks

這個階段主要執行一些系統操作帶來的回調函數,如 TCP 錯誤,如果 TCP 嘗試鏈接時出現 ECONNREFUSED 錯誤 ,一些 *nix 會把這個錯誤報告給 Node.js。而這個錯誤報告會先進入隊列中,然后在 I/O callbacks 階段執行。

poll

poll 階段有兩個主要功能:

也會執行時間定時器到達期望時間的回調函數

執行事件循環列表(poll queue)里的函數

當 Event Loop 進入 poll 階段并且沒有其余的定時器,那么:

如果事件循環列表不為空,則迭代同步的執行隊列中的函數。

如果事件循環列表為空,則判斷是否有 setImmediate() 函數待執行。如果有結束 poll 階段,直接到

check 階段。如果沒有,則等待回調函數進入隊列并立即執行。

check

在 poll 階段結束之后,執行 setImmediate()

close

突然結束的事件的回調函數會在這里觸發,如果 socket.destroy(),那么 close 會被觸發在這個階段,也有可能通過 process.nextTick() 來觸發。

setImmediate()、setTimeout()、process.nextTick()

這里要說明一下 process.nextTick() 是在下次事件循環之前運行,如果把 process.nextTick()setImmediate() 寫在一起,那么是 process.nextTick() 先執行。nextimmediate 快,官方也說這個函數命名有問題,但是因為歷史存留沒辦法解決。

process.nextTick(() => {
  console.log("nextTick");
});
setImmediate(() => {
  console.log("setImmediate");
});
setTimeout(() => {
  console.log("setTimeout"); 
}, 0)

// 執行結果,nextTick, setTimeout, setImmediate
// 查看 Node.js 源碼,setTimeout(fun, 0) 會轉化成 setTimeout(fun, 1),所以在這種簡單的情況下,對于不同設備,setImmediate 有可能早于 setTimeout 執行。
總結

理解事件循環,會知道 JavaScript 如何無阻塞運行的,以及它簡潔的開發思路和事件驅動風格。

作者:肖沐宸,github。

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

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

相關文章

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

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

    lavor 評論0 收藏0
  • JavaScript 事件循環(譯文JavaScript Event Loop

    摘要:事件循環了解了在引擎中是如何工作了之后,來看下如何使用異步回調函數來避免代碼。從回調函數被放入后秒鐘,把移到中。由于事件循環持續地監測調用棧是否已空,此時它一注意到調用棧空了,就調用并創建一個新的調用棧。 聽多了JavaScript單線程,異步,V8,便會很想去知道JavaScript是如何利用單線程來實現所謂的異步的。我參考了一些文章,了解到一個很重要的詞匯:事件循環(Event L...

    K_B_Z 評論0 收藏0
  • 關于瀏覽器Event Loop

    摘要:的宿主最開始本身就是瀏覽器,處理用戶的交互事件。既然是單線程的,那就意味著任務需要排隊,只有前一個任務執行完畢,下一個任務才能開始,于是就有了任務隊列。事件循環有兩種用于瀏覽上下文的事件循環和用于的事件循環。 最近看到Event Loop這個詞出現的頻率有點高,于是查閱各方資料在此記錄一下。 先不說概念,我們來看段代碼: console.log(script start); setT...

    youkede 評論0 收藏0
  • JS異步詳解 - 瀏覽器/Node/事件循環/消息隊列/宏任務/微任務

    js異步歷史 一個 JavaScript 引擎會常駐于內存中,它等待著我們把JavaScript 代碼或者函數傳遞給它執行 在 ES3 和更早的版本中,JavaScript 本身還沒有異步執行代碼的能力,引擎就把代碼直接順次執行了,異步任務都是宿主環境(瀏覽器)發起的(setTimeout、AJAX等)。 在 ES5 之后,JavaScript 引入了 Promise,這樣,不需要瀏覽器的安排,J...

    awesome23 評論0 收藏0
  • JavaScript執行機制、事件循環

    摘要:曾經的理解首先,是單線程語言,也就意味著同一個時間只能做一件事,那么為什么不是多線程呢這樣還能提高效率啊假定同時有兩個線程,一個線程在某個節點上編輯了內容,而另一個線程刪除了這個節點,這時瀏覽器就很懵逼了,到底以執行哪個操作呢所以,設計者把 Event Loop曾經的理解 首先,JS是單線程語言,也就意味著同一個時間只能做一件事,那么 為什么JavaScript不是多線程呢?這樣還能提...

    rose 評論0 收藏0

發表評論

0條評論

luckyyulin

|高級講師

TA的文章

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