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

資訊專欄INFORMATION COLUMN

淺析 JS 中的 EventLoop 事件循環(huán)(新手向)

chadLi / 1376人閱讀

摘要:同時,如果執(zhí)行的過程中發(fā)現(xiàn)其他函數(shù),繼續(xù)入棧然后執(zhí)行。上面我們討論的其實(shí)都是同步代碼,代碼在運(yùn)行的時候只用調(diào)用棧解釋就可以了。

Event Loop 這個概念相信大家或多或少都了解過,但是有一次被一個小伙伴問到它具體的原理的時候,感覺自己只知道個大概印象,于是計(jì)劃著寫一篇文章,用輸出倒逼輸入,讓自己重新學(xué)習(xí)這個概念,同時也能幫助更多的人理解它~

概念

JavaScript 是一門 單線程 語言,即同一時間只能執(zhí)行一個任務(wù),即代碼執(zhí)行是同步并且阻塞的。

eg. 這就像只有一個窗口的銀行,客戶需要一個一個排隊(duì)辦理業(yè)務(wù)。

只能同步執(zhí)行肯定是有問題的,所以 JS 有了一個用來實(shí)現(xiàn)異步的函數(shù):setTimeout

下面要講的 Event Loop 就是為了確保 異步代碼 可以在 同步代碼 執(zhí)行后繼續(xù)執(zhí)行的。

由于涉及到的相關(guān)概念較多,我們先從最簡單的來。

隊(duì)列(Queue)

隊(duì)列 是一種 FIFO(First In, First Out) 的數(shù)據(jù)結(jié)構(gòu),它的特點(diǎn)就是 先進(jìn)先出

eg. 生活中最常見的例子就是排隊(duì)啦,排在隊(duì)伍最前面的人最先被提供服務(wù)。
棧(Stack)

是一種 LIFO(Last In, First Out)的數(shù)據(jù)結(jié)構(gòu),特點(diǎn)即 后進(jìn)先出

eg. 大家都吃過桶裝薯片吧~薯片在包裝的時候只能從頂部放入,而吃的時候也只能從頂部拿出,這就叫后進(jìn)先出哈
調(diào)用棧(Call Stack)

棧我們已經(jīng)知道了,那么什么是 調(diào)用棧 呢 ?

它本質(zhì)上當(dāng)然還是個棧啦 廢話,關(guān)鍵在于它里面裝的東西,是一個個待執(zhí)行的函數(shù)。

Event Loop 會一直檢查 Call Stack 中是否有函數(shù)需要執(zhí)行,如果有,就從棧頂依次執(zhí)行。同時,如果執(zhí)行的過程中發(fā)現(xiàn)其他函數(shù),繼續(xù)入棧然后執(zhí)行。

先拿兩個函數(shù)來說:

???/p>

現(xiàn)在執(zhí)行到一個 函數(shù)A,函數(shù)A 入棧

函數(shù)A 又調(diào)用了 函數(shù)B,函數(shù)B 入棧

函數(shù)B 執(zhí)行完后 出棧

然后繼續(xù)執(zhí)行 函數(shù)A,執(zhí)行完后A也 出棧

???/p>

更復(fù)雜一點(diǎn)的話,來看一段代碼:

這段代碼在 調(diào)用棧中的運(yùn)行順序如下圖:

這個調(diào)用棧其實(shí)大家經(jīng)常會見到,就是在控制臺報(bào)錯的時候,錯誤信息顯示的就是當(dāng)前時刻調(diào)用棧的狀態(tài)。

But, 上面我們討論的其實(shí)都是同步代碼,代碼在運(yùn)行的時候只用 調(diào)用棧 解釋就可以了。

那么,假如我們發(fā)起了一個網(wǎng)絡(luò)請求(request),或者設(shè)置了一個定時器延時(setTimeout),一段時間后的代碼(回調(diào)函數(shù))肯定不是直接被加到調(diào)用棧吧?

這時就要引出 事件表格(Event Table)事件隊(duì)列 (Event Queue)

Event Table

Event Table 可以理解成一張 事件->回調(diào)函數(shù) 對應(yīng)表

它就是用來存儲 JavaScript 中的異步事件 (request, setTimeout, IO等) 及其對應(yīng)的回調(diào)函數(shù)的列表
Event Queue

Event Queue 簡單理解就是 回調(diào)函數(shù) 隊(duì)列,所以它也叫 Callback Queue

當(dāng) Event Table 中的事件被觸發(fā),事件對應(yīng)的 回調(diào)函數(shù) 就會被 push 進(jìn)這個 Event Queue,然后等待被執(zhí)行
Event Loop

先來看一個流程圖:

開始,任務(wù)先進(jìn)入 Call Stack

同步任務(wù)直接在棧中等待被執(zhí)行,異步任務(wù)從 Call Stack 移入到 Event Table 注冊

當(dāng)對應(yīng)的事件觸發(fā)(或延遲到指定時間),Event Table 會將事件回調(diào)函數(shù)移入 Event Queue 等待

當(dāng) Call Stack 中沒有任務(wù),就從 Event Queue 中拿出一個任務(wù)放入 Call Stack

Event Loop 指的就是這一整個圈圈:

它不停檢查 Call Stack 中是否有任務(wù)(也叫棧幀)需要執(zhí)行,如果沒有,就檢查 Event Queue,從中彈出一個任務(wù),放入 Call Stack 中,如此往復(fù)循環(huán)。

好啦,不知道有沒有看明白呢?放一張更經(jīng)典的圖:

其中與 Event Queue 對應(yīng)的還有一個叫 Job Queue,它主要是用來執(zhí)行 Promise 的,這兩種 Queue 有什么區(qū)別呢?

這就涉及到 宏任務(wù) (macro task) 和 微任務(wù) (micro task) 了,我們放在下篇再講~

參考文章

原文鏈接
MDN EventLoop
javascript-event-loop
understanding-js-the-event-loop
這一次,徹底弄懂JavaScript執(zhí)行機(jī)制
understanding-event-loop-call-stack-event-job-queue-in-javascript

歡迎關(guān)注我的公眾號:碼力全開

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

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

相關(guān)文章

  • 淺析 JS 事件循環(huán)之 Microtask 和 Macrotask

    摘要:常見應(yīng)用則是為了完成一些更新應(yīng)用程序狀態(tài)的較小的任務(wù),如處理的回調(diào)和的修改,以便讓這些任務(wù)在瀏覽器重新渲染之前執(zhí)行。常見應(yīng)用執(zhí)行順序的實(shí)現(xiàn)需要至少一個和至少一個。 簡介 我們在上一篇 《淺析 JS 中的EventLoop 事件循環(huán)》 中提到一個 Event Queue,其實(shí)在事件循環(huán)中 queue 一共有兩種,還有一種叫 Job Queue 其中 Event Queue 在 HTML...

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

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

    Riddler 評論0 收藏0
  • 事件循環(huán)(EventLoop)的學(xué)習(xí)總結(jié)

    摘要:事件循環(huán)當(dāng)進(jìn)程啟動時,會創(chuàng)建一個循環(huán),每個循環(huán)通過內(nèi)部的觀察者來查看是否有事件需要處理,如果有就取出事件和它相關(guān)的回調(diào)函數(shù)去執(zhí)行,執(zhí)行完以后就進(jìn)入下一個循環(huán),如果不再有就退出進(jìn)程。 前言 在學(xué)習(xí)eventloop之前,我們需要復(fù)習(xí)一下js的單線程和異步。雖說js是單線程的,但是在瀏覽器和Node中都做了相應(yīng)的處理。如瀏覽器中的web workers(工作線程),Node中的child_...

    lentoo 評論0 收藏0
  • 事件循環(huán)(EventLoop)的學(xué)習(xí)總結(jié)

    摘要:事件循環(huán)當(dāng)進(jìn)程啟動時,會創(chuàng)建一個循環(huán),每個循環(huán)通過內(nèi)部的觀察者來查看是否有事件需要處理,如果有就取出事件和它相關(guān)的回調(diào)函數(shù)去執(zhí)行,執(zhí)行完以后就進(jìn)入下一個循環(huán),如果不再有就退出進(jìn)程。 前言 在學(xué)習(xí)eventloop之前,我們需要復(fù)習(xí)一下js的單線程和異步。雖說js是單線程的,但是在瀏覽器和Node中都做了相應(yīng)的處理。如瀏覽器中的web workers(工作線程),Node中的child_...

    hizengzeng 評論0 收藏0
  • 事件循環(huán)(EventLoop)的學(xué)習(xí)總結(jié)

    摘要:事件循環(huán)當(dāng)進(jìn)程啟動時,會創(chuàng)建一個循環(huán),每個循環(huán)通過內(nèi)部的觀察者來查看是否有事件需要處理,如果有就取出事件和它相關(guān)的回調(diào)函數(shù)去執(zhí)行,執(zhí)行完以后就進(jìn)入下一個循環(huán),如果不再有就退出進(jìn)程。 前言 在學(xué)習(xí)eventloop之前,我們需要復(fù)習(xí)一下js的單線程和異步。雖說js是單線程的,但是在瀏覽器和Node中都做了相應(yīng)的處理。如瀏覽器中的web workers(工作線程),Node中的child_...

    ninefive 評論0 收藏0

發(fā)表評論

0條評論

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