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

資訊專欄INFORMATION COLUMN

事件循環(huán)機制(event loop)

tain335 / 3560人閱讀

摘要:了解事件循環(huán)機制有助于理解的執(zhí)行過程,同時這也是面試常見題。那么這個回調(diào)函數(shù)將在何時由誰執(zhí)行呢已知是瀏覽器環(huán)境提供的,因此瀏覽器將對它進行處理,瀏覽器會在本次事件完成,即計時結(jié)束后,將回調(diào)函數(shù)加入循環(huán)隊列中,然后等待被加入執(zhí)行棧執(zhí)行。

如果有人問JavaScript是什么,也許你會說它是一個單線程、非阻塞、異步、解釋型的腳本語言。那么作為一個單線程語言,它是怎么實現(xiàn)非阻塞、異步的?這就涉及到了瀏覽器的事件循環(huán)機制,事件循環(huán)并非由ECMAScript定義,而是在HTML Standard中定義。了解事件循環(huán)機制有助于理解JS的執(zhí)行過程,同時這也是面試常見題。
在瀏覽器中,瀏覽器會提供JavaScript的運行環(huán)境,如Chrome的V8,以及一些Web API,如DOM、Ajax、setTimeout等。

如圖,在運行環(huán)境中存在一個執(zhí)行棧stack,為當(dāng)前正在執(zhí)行的JS代碼,當(dāng)調(diào)用一個普通函數(shù)時,會生成新的作用域,并入棧,待執(zhí)行結(jié)束后出棧,此時不涉及異步操作。但是當(dāng)調(diào)用了異步函數(shù)時,情況就有所不同了,以setTimeout為例,當(dāng)調(diào)用了setTimeout后,回調(diào)函數(shù)將在一段時間后才執(zhí)行,由于JavaScript是異步,它不會等待回調(diào)函數(shù)執(zhí)行,而是會立即獲得結(jié)果并從上至下繼續(xù)執(zhí)行代碼。那么這個回調(diào)函數(shù)將在何時由誰執(zhí)行呢?已知setTimeout是瀏覽器環(huán)境提供的API,因此瀏覽器將對它進行處理,瀏覽器會在本次事件完成,即計時結(jié)束后,將回調(diào)函數(shù)加入循環(huán)隊列task queue中,然后等待被加入執(zhí)行棧執(zhí)行。
循環(huán)隊列中的任務(wù)被調(diào)用的時機,是當(dāng)執(zhí)行棧為空,即當(dāng)前事件執(zhí)行結(jié)束后,此時瀏覽器會查看循環(huán)隊列是否為空,在非空時以FIFO的方式調(diào)用隊列中的事件,加入執(zhí)行棧,當(dāng)執(zhí)行棧再次為空時,再從循環(huán)隊列中查找任務(wù),這就形成了事件循環(huán)event loop,瀏覽器通過該機制讓單線程的JS可以執(zhí)行異步任務(wù)。這就可以解釋一些很常見的關(guān)于setTimeout執(zhí)行順序的面試題。除了setTImeout外,常見的task任務(wù)源還有setInterval、setImmediate、I/O、UI rendering、XMLHttpRequest等。
除了以上普通的task,瀏覽器還引入了microtask的概念,microtask存儲在microtask queue中,它的執(zhí)行時機與task不同,當(dāng)執(zhí)行棧為空時,優(yōu)先調(diào)用microtask中的任務(wù)執(zhí)行,因此只有當(dāng)microtask queue為空時,才會調(diào)用循環(huán)隊列中的任務(wù)。常見的microtask源有promise、process.nextTick,關(guān)于promise的執(zhí)行時機,也是面試較為常見的問題。
接下來就以一段代碼的執(zhí)行過程為例,解釋event loop。

1 console.log(1);
2 setTimeout(() => {console.log(5)}, 0);
3 let promise = new Promise((resolve, reject) => {
    console.log(2)
    resolve()
    })
4 promise.then(() => {console.log(4)});
5 console.log(3)

請問以上代碼的執(zhí)行結(jié)果?
我們試著縷一縷這些代碼的執(zhí)行順序,首先這一整段代碼會被加入執(zhí)行棧中,然后從上至下依次解釋執(zhí)行
1:直接輸出1
2:此時調(diào)用了setTimeout,因此回調(diào)函數(shù)會在0ms后加入到循環(huán)隊列中
3:此時實例化了一個promise,會立即執(zhí)行實例化時的代碼,因此會輸出2
4:此時調(diào)用了promise的then方法,該方法的回調(diào)函數(shù)會被加入到microtask queue中
5:直接輸出3
到此,執(zhí)行棧執(zhí)行結(jié)束,此時根據(jù)事件循環(huán)機制,首先查看microtask queue是否為空,會發(fā)現(xiàn)隊列中有promise.then方法加入的回調(diào)函數(shù),將其調(diào)入執(zhí)行棧執(zhí)行,輸出4。執(zhí)行棧再次執(zhí)行結(jié)束,再查看microtask queue,此時為空,接著查看任務(wù)隊列task queue,會發(fā)現(xiàn)由setTimeout方法加入的回調(diào)函數(shù),調(diào)入執(zhí)行棧執(zhí)行,輸出5。因此最后的輸出順序是 1 -> 2 -> 3 -> 4 -> 5

以上是關(guān)于瀏覽器端事件循環(huán)的個人理解,為什么要強調(diào)是瀏覽器端,因為從以上解釋可以看出JS只是運行在瀏覽器提供的執(zhí)行環(huán)境中,事件循環(huán)其實是由瀏覽器環(huán)境實現(xiàn)的,除了瀏覽器,還有Node環(huán)境,而Node環(huán)境與瀏覽器環(huán)境又有著許多差別,Node環(huán)境中的事件循環(huán)與瀏覽器端存在一些差異,待有空了再寫一篇關(guān)于Node環(huán)境中的事件循環(huán)。關(guān)于瀏覽器事件循環(huán),可以觀看https://www.youtube.com/watch...

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/105138.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 - JS執(zhí)行機制

    摘要:心塞塞根據(jù)規(guī)范,事件循環(huán)是通過任務(wù)隊列的機制來進行協(xié)調(diào)的。等便是任務(wù)源,而進入任務(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 的事件循環(huán)(Event Loop)機制以及實例講解

    摘要:主線程要明確的一點是,主線程跟執(zhí)行棧是不同概念,主線程規(guī)定現(xiàn)在執(zhí)行執(zhí)行棧中的哪個事件。主線程循環(huán)即主線程會不停的從執(zhí)行棧中讀取事件,會執(zhí)行完所有棧中的同步代碼。以上參考資料詳解中的事件循環(huán)機制中的事件循環(huán)運行機制詳解再談 showImg(https://segmentfault.com/img/remote/1460000015317437?w=1920&h=1080); 前言 大家都...

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

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

    rose 評論0 收藏0
  • 【Node.js】理解事件循環(huán)機制

    摘要:前沿是基于引擎的運行環(huán)境具有事件驅(qū)動非阻塞等特點結(jié)合具有網(wǎng)絡(luò)編程文件系統(tǒng)等服務(wù)端的功能用庫進行異步事件處理線程的單線程含義實際上說的是執(zhí)行同步代碼的主線程一個程序的啟動不止是分配了一個線程,而是我們只能在一個線程執(zhí)行代碼當(dāng)出現(xiàn)資源調(diào)用連接等 前沿 Node.js 是基于V8引擎的javascript運行環(huán)境. Node.js具有事件驅(qū)動, 非阻塞I/O等特點. 結(jié)合Node API, ...

    Riddler 評論0 收藏0
  • 10分鐘理解JS引擎的執(zhí)行機制

    摘要:深入理解引擎的執(zhí)行機制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實現(xiàn)異步的呢中的中的說說首先請牢記點是單線程語言的是的執(zhí)行機制。 深入理解JS引擎的執(zhí)行機制 1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實現(xiàn)異步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.說說setTimeout 首先,請牢記2...

    zzbo 評論0 收藏0

發(fā)表評論

0條評論

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