成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 事件循環(huán)(譯文JavaScript Event Loop)

K_B_Z / 2003人閱讀

摘要:事件循環(huán)了解了在引擎中是如何工作了之后,來看下如何使用異步回調函數(shù)來避免代碼。從回調函數(shù)被放入后秒鐘,把移到中。由于事件循環(huán)持續(xù)地監(jiān)測調用棧是否已空,此時它一注意到調用??樟?,就調用并創(chuàng)建一個新的調用棧。

聽多了JavaScript單線程,異步,V8,便會很想去知道JavaScript是如何利用單線程來實現(xiàn)所謂的異步的。我參考了一些文章,了解到一個很重要的詞匯:事件循環(huán)(Event Loop)。在這些文章中,有:

阮一峰老師的JavaScript 運行機制詳解:再談Event Loop

Philip Roberts的What the heck is the event loop anyway?

Erin Swenson-Healey的The JavaScript Event Loop: Explained等。

這些文章都講得非常好,讓我對Event Loop的機制有了大概的了解。
異步在JavaScript的重要性,也意味著理解Event Loop的必要性,不然怎么敢輕易使用setTimeout和setInterval這些咧。
這里我還是通過翻譯一篇文章來解釋Event Loop,原文點這里Willson Mock:What is the JavaScript Event Loop?下邊的圖也都引用自這篇文章。

JavaScript Engine:JavaScript 引擎

截止到目前(原文編寫時間:5 July 2014),在各種JavaScript 引擎的實現(xiàn)里邊,最出名的當屬Google Chrome的V8引擎了,既能在瀏覽器中使用,也能通過NodeJS在服務器端使用。但究竟JavaScript引擎是干什么用的?其實很簡單--它的任務就是遍歷應用中的每一行JavaScript代碼,并且一次執(zhí)行一行,意味著JavaScript是單線程的。這里最大的影響是:如果在JavaScript代碼中有地方會占用大量的時間,那后面的代碼都會被block住。
那么JavaScript引擎怎么知道如何一次處理一行JavaScript代碼?它使用的是一個調用棧call stack。你可以把調用棧比作電梯--第一個進電梯的會最后一個出電梯,最后進電梯的會最先出。
看個栗子:

/* Within main.js */

var firstFunction = function () {  
  console.log("I"m first!");
};

var secondFunction = function () {  
  firstFunction();
  console.log("I"m second!");
};

secondFunction();

/* Results:
 * => I"m first!
 * => I"m second!
 */

下邊是調用棧的情況:

Main.js 執(zhí)行

調用secondFunction

調用secondFunction引起調用firstFunction

執(zhí)行firstFunction,輸出“I"m first!”,接著由于firstFunction執(zhí)行完畢,firstFunction會從調用棧中彈出。

secondFunction繼續(xù)執(zhí)行,輸出“I"m second!”。接著由于secondFunction執(zhí)行完畢,secondFunction從調用棧中彈出。

最后,main.js執(zhí)行完畢,也從棧中彈出。

Event Loop:事件循環(huán)

了解了call stack在JavaScript引擎中是如何工作了之后,來看下如何使用異步回調函數(shù)來避免blocking 代碼。(譯者注:回調函數(shù)有多種實現(xiàn)方式,最常見的有:在函數(shù)中使用函數(shù)作用參數(shù)etc。)setTimeout就是使用的回調函數(shù)。看個栗子:

/* Within main.js */

var firstFunction = function () {  
 console.log("I"m first!");
};

var secondFunction = function () {  
 setTimeout(firstFunction, 5000);
 console.log("I"m second!");
};

secondFunction();

/* Results:
 * => I"m second!
 * (And 5 seconds later)
 * => I"m first!
 */

下邊模擬調用棧(在上個栗子的基礎上我們這次推前點)

...

secondFunction調用setTimeout,setTimeout入棧:

setTimeout執(zhí)行后,瀏覽器會把setTimeout的回調函數(shù)(在這個栗子中是firstFunction)放到Event Table中。Event Table 就是個注冊站:調用棧讓Event Table注冊一個函數(shù),該函數(shù)會在5秒之后被調用。當指定的事情發(fā)生時,Event Table會將這個函數(shù)移到Event Queue。Event Queue其實就是個緩沖區(qū)域,這里的函數(shù)等著被調用并移到調用棧。
問題來了,什么時候函數(shù)會從Event Queue移到調用棧咧?JavaScript引擎依據(jù)一條規(guī)則:有一個monitoring process(不知翻譯成啥好)會持續(xù)不斷地檢查調用棧是否為空,一旦為空,它會檢查Event Queue里邊是否有等待被調用的函數(shù)。如果存在,它就會調用這個Queue中第一個函數(shù)并將其移到調用棧中。如果Event Queue為空,那么這個monitoring process會繼續(xù)不定期的檢查。這一整個過程就是Event Loop

一旦回調函數(shù)加入到Event表中,代碼不會被block住,瀏覽器不會等待5秒之后再繼續(xù)處理接下去的代碼,相反,瀏覽器繼續(xù)執(zhí)行secondFunction的下一行代碼,console.log。

在background,Event Table會持續(xù)地監(jiān)測是否有事件觸發(fā),將函數(shù)移到Event Queue中。在這個栗子中,secondFunction執(zhí)行完畢,接著main.js也執(zhí)行完畢。

從回調函數(shù)被放入Event Table后5秒鐘,Event Table把firstFucntion移到Event Queue中。

由于事件循環(huán)持續(xù)地監(jiān)測調用棧是否已空,此時它一注意到調用??樟?,就調用firstFunction并創(chuàng)建一個新的調用棧。

一旦firstFunction執(zhí)行完畢,調用??樟耍珽vent Table里也沒有注冊函數(shù),Event Queue也為空。

總結

雖然這樣的解釋掩蓋了實際JavaScript引擎、Event Table、Event Queue和Event Loop的具體實現(xiàn)細節(jié),但是對于大部分人來說,我們只需要對JavaScript執(zhí)行異步函數(shù)時會發(fā)生什么有個大概的了解即可。
(譯到此)

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

轉載請注明本文地址:http://systransis.cn/yun/80310.html

相關文章

  • 譯文:JS事件循環(huán)機制(event loop)之宏任務、微任務

    摘要:譯文事件循環(huán)機制之宏任務微任務原文標題這是一篇谷歌大神文章,寫得非常精彩。為什么會出現(xiàn)這樣打印順序呢要理解這些你首先需要對事件循環(huán)機制處理宏任務和微任務的方式有了解。 譯文:JS事件循環(huán)機制(event loop)之宏任務、微任務 原文標題:《Tasks, microtasks, queues and schedules》 這是一篇谷歌大神文章,寫得非常精彩。譯者想借這次翻譯深入學習一...

    nemo 評論0 收藏0
  • 初窺JavaScript事件機制的實現(xiàn)(一)—— Node.js事件驅動實現(xiàn)概覽

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

    lavor 評論0 收藏0
  • JavaScript Event loop 事件循環(huán)

    摘要:階段有兩個主要功能也會執(zhí)行時間定時器到達期望時間的回調函數(shù)執(zhí)行事件循環(huán)列表里的函數(shù)當進入階段并且沒有其余的定時器,那么如果事件循環(huán)列表不為空,則迭代同步的執(zhí)行隊列中的函數(shù)。如果沒有,則等待回調函數(shù)進入隊列并立即執(zhí)行。 Event Loop 本文以 Node.js 為例,講解 Event Loop 在 Node.js 的實現(xiàn),原文,JavaScript 中的實現(xiàn)大同小異。 什么是 Eve...

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

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

    youkede 評論0 收藏0
  • 瀏覽器與NodeJS的EventLoop異同,以及部分機制。

    摘要:瀏覽器與的異同,以及部分機制有人對部分迷惑,本身構造函數(shù)是同步的,是異步。瀏覽器的的已全部分析完成,過程中引用阮一峰博客,知乎,部分文章內容,侵刪。 瀏覽器與NodeJS的EventLoop異同,以及部分機制 PS:有人對promise部分迷惑,Promise本身構造函數(shù)是同步的,.then是異步。---- 2018/7/6 22:35修改 javascript 是一門單線程的腳本...

    jubincn 評論0 收藏0

發(fā)表評論

0條評論

K_B_Z

|高級講師

TA的文章

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