亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

簡單理解 JavaScript Event Loop

cjie / 1282人閱讀

摘要:由此可以認(rèn)為,實際上是一系列的回調(diào)函數(shù)集合。此時瀏覽器會在其它線程中執(zhí)行異步操作,操作完成后將回調(diào)函數(shù)放入主線程任務(wù)隊列中。當(dāng)主線程將執(zhí)行棧中的函數(shù)執(zhí)行完畢后,再次讀取任務(wù)隊列,形成循環(huán)。

先看一段代碼,也是一道經(jīng)典面試題:

(function test() {
    setTimeout(function() {console.log(4)}, 0);
    new Promise(function executor(resolve) {
        console.log(1);
        for( var i=0 ; i<10000 ; i++ ) {
            i == 9999 && resolve();
        }
        console.log(2);
    }).then(function() {
        console.log(5);
    });
    console.log(3);
})()

其輸出結(jié)果為:

// 1
// 2
// 3
// 5
// 4


我們知道,JavaScript 在同一時間片內(nèi)只能執(zhí)行一個任務(wù):

主線程會依次執(zhí)行代碼,當(dāng)執(zhí)行到函數(shù)的時候會將函數(shù)加入執(zhí)行棧,當(dāng)函數(shù)執(zhí)行完畢后再將其出棧,直至代碼執(zhí)行完畢。當(dāng)執(zhí)行棧為空時,runtime 會從任務(wù)隊列(先入先出)中取出待執(zhí)行的回調(diào)函數(shù)并執(zhí)行,入棧、出棧的過程同上。這個機制就叫做 Event Loop。

由此可以認(rèn)為,Event Loop實際上是一系列的回調(diào)函數(shù)集合。

舉例來說:在瀏覽器中,對于網(wǎng)絡(luò)請求等需要等待一段時間才會返回結(jié)果的操作,我們通常采用異步回調(diào)來處理,這個回調(diào)就會放入任務(wù)隊列中。此時瀏覽器會在其它線程中執(zhí)行異步操作,操作完成后將回調(diào)函數(shù)放入主線程任務(wù)隊列中。Event Loop負(fù)責(zé)在主線程執(zhí)行完畢后將任務(wù)隊列中的函數(shù)放入執(zhí)行棧中,由主線程執(zhí)行。當(dāng)主線程將執(zhí)行棧中的函數(shù)執(zhí)行完畢后,再次讀取任務(wù)隊列,形成循環(huán)。所以即使主線程阻塞了,任務(wù)隊列依然能夠被添加函數(shù),因為任務(wù)隊列的添加是由瀏覽器負(fù)責(zé)的。(不同的 runtime 實現(xiàn)可能不同)

另外需要注意的是 Promise.then 是異步執(zhí)行的,而創(chuàng)建 Promise 實例是同步執(zhí)行的。這就解釋了為什么1、2、3輸出在4、5之前。

但為什么5 會輸出在4前面呢?

JavaScript 中的任務(wù)又分為MacroTask 與 MicroTask 兩種。

典型的 MacroTask 包含了 :

setTimeout

setInterval

setImmediate

requestAnimationFrame

I/O

UI rendering

而常見的MicroTask 包含了

process.nextTick

Promises

Object.observe

MutationObserver

Event Loop 中有一個或多個Task Queue,即MacroTask Queue,僅有一個Job Queue,即MicroTask Queue。Task Queue的執(zhí)行是按照回調(diào)順序先入先出,而在 MacroTask 的執(zhí)行間隙中會清空已有的 MicroTask Queue

回到代碼中,setTimeout(function() {console.log(4)}, 0); 既然延遲設(shè)置為0,為什么5會在4之前輸入呢?

那是因為setTimeout設(shè)置為0的時候,runtime其實并不是0,在主流瀏覽器中會將其設(shè)置為4,而 node 則會將其設(shè)置為1。那么現(xiàn)在代碼的執(zhí)行順序就很清晰了:

console.log(1);    // 創(chuàng)建 Promise 主線程執(zhí)行
...
console.log(2); // 創(chuàng)建 Promise 主線程執(zhí)行

console.log(3); // test 函數(shù)立即執(zhí)行, 主線程執(zhí)行
... 
console.log(5); // 主線程執(zhí)行完畢,執(zhí)行MicroTask Queue,即 promise.then
... 
console.log(4);    // 執(zhí)行 setTimeout(4)



參考資料:

https://developer.mozilla.org...

https://html.spec.whatwg.org/...

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/94529.html

相關(guān)文章

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

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

    lavor 評論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個例子其實是在這個中找到的,第一個使用的版本是,這個版本的實現(xiàn)是采用了,而后因為的里的有,于是尤雨溪更改了實現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調(diào)放入的隊列。 結(jié)論 對于event loop 可以抽象成一段簡單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    springDevBird 評論0 收藏0
  • event loop 與 vue

    摘要:但是導(dǎo)致了很明顯的性能問題。上述兩個例子其實是在這個中找到的,第一個使用的版本是,這個版本的實現(xiàn)是采用了,而后因為的里的有,于是尤雨溪更改了實現(xiàn),換成了,也就是后一個所使用的。后來尤雨溪了解到是將回調(diào)放入的隊列。 結(jié)論 對于event loop 可以抽象成一段簡單的代碼表示 for (macroTask of macroTaskQueue) { // 1. Handle cur...

    Barry_Ng 評論0 收藏0
  • Event Loop - JS執(zhí)行機制

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

    muddyway 評論0 收藏0
  • 理解JS中的Event Loop機制

    摘要:前言前幾天在理解的事件環(huán)機制中引發(fā)了我對瀏覽器里的好奇。接下來理解瀏覽器中的,先看一張圖堆和棧堆是用戶主動請求而劃分出來的內(nèi)存區(qū)域,比如你,就是將一個對象存入堆中,可以理解為存對象。廢話不多說,直接上圖個人理解。參考資料運行機制詳解再談 前言 前幾天在理解node的事件環(huán)機制中引發(fā)了我對瀏覽器里Event Loop的好奇。我們都知道javascript是單線程的,任務(wù)是需要一個一個按順...

    MASAILA 評論0 收藏0
  • JavaScript執(zhí)行機制、事件循環(huán)

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

    rose 評論0 收藏0

發(fā)表評論

0條評論

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