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

資訊專欄INFORMATION COLUMN

Javascript event loop

reclay / 2038人閱讀

摘要:包括了操作例如事件綁定,這類操作。每個(gè)結(jié)束后,都會(huì)進(jìn)行也就是檢查是否有在等待執(zhí)行,根據(jù)先進(jìn)先出,依次執(zhí)行。簡單來說,會(huì)檢查是否有需要處理的,如果為空時(shí),則會(huì)按照先進(jìn)先出的順序來處理中的。

眾所周知, javascript是一個(gè)單線程語言。單線程也就意味著只有一個(gè)stack(調(diào)用棧),一次只能做一件事。那么又是如何實(shí)現(xiàn)異步操作?先來了解幾個(gè)關(guān)鍵的術(shù)語。

Call Stack 調(diào)用棧


如圖所示,在運(yùn)行過程中,所有相關(guān)的變量是存于heap中,而call stack中是正在執(zhí)行的代碼。通過F12 developer tool 在debug模式也可以看到此時(shí)的call stack情況。下圖是最簡單的一種情況,函數(shù)根據(jù)調(diào)用順序依次進(jìn)入call stack,執(zhí)行后再依次彈出(stack后進(jìn)先出)。

Task Queue

那么JavaScript是怎么實(shí)現(xiàn)異步的呢?重要的task queue(任務(wù)隊(duì)列)來了。
一般而言,我們所理解的異步操作,都是放入task queue進(jìn)行等待。如下代碼所示,console.log("start")進(jìn)入call stack。而setTimeout是進(jìn)入task queue進(jìn)行等待。這里設(shè)置的時(shí)間為0,則是立即放入task queue,?? 是放入task queue而不是立即執(zhí)行。
只有在call stack為空的時(shí)候,event loop會(huì)講task queue中的任務(wù)調(diào)入call stack再執(zhí)行。

console.log("start");

setTimeout(()=>{
    console.log("hey")
}
, 0)

console.log("end");

輸出結(jié)果:

start
end
hey

Macrotask

一般而言,macrotask queue就是我們常說的task queue(也有人稱為message queue)。Macrotask包括了setTimeout, Dom 操作(例如onLoad), click/mouse事件綁定,fetch response這類操作。實(shí)際上這些都是瀏覽器提供的API,所以在執(zhí)行時(shí)是有它們多帶帶的線程去進(jìn)行操作。舉個(gè)例子,setTimeout()設(shè)置了2s的延遲,是瀏覽器設(shè)置了timer來計(jì)時(shí),是另外的線程在等待2秒,js主線程不受影響,2s后回調(diào)函數(shù)再進(jìn)入task queue。

(function() {

  console.log("this is the start");

  setTimeout(function cb() {
    console.log("this is a msg from call back");
  });

  console.log("this is just a message");

  setTimeout(function cb1() {
    console.log("this is a msg from call back1");
  }, 0);

  console.log("this is the end");

})();

// "this is the start"
// "this is just a message"
// "this is the end"
// undefined (注意此時(shí)是函數(shù)返回,因?yàn)闆]有設(shè)置返回值故輸出undefined) 
// "this is a msg from call back"
// "this is a msg from call back1"
Microtask

ES6提供了Promise來進(jìn)行異步操作。為了區(qū)別開task稱為microtask。同上也有一個(gè)queue (job queue)來處理microtask。job queue擁有更高的優(yōu)先級(jí)。每個(gè)task結(jié)束后,都會(huì)進(jìn)行perform a microtask checkpoint.也就是檢查job queue是否有microtask在等待執(zhí)行,根據(jù)先進(jìn)先出,依次執(zhí)行。

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

Promise.resolve().then(function() {
  console.log("promise1");
}).then(function() {
  console.log("promise2");
});


// script start
// promise1
// promise2
// setTimeout
Event loop

簡單來說,event loop會(huì)檢查queue是否有需要處理的task,如果call stack為空時(shí),則會(huì)按照先進(jìn)先出的順序來處理queue中的task。而task分為microtask【Promise】和macrotask【setTimeout/DOM events/fetch】。優(yōu)先處理microtask。一次event loop只會(huì)處理一次macrotask,并且是當(dāng)microtask queue都處理結(jié)束后才會(huì)去處理macrotasks。

while (queue.waitForMessage()) {
  queue.processNextMessage();
}

強(qiáng)烈推薦大家去看 https://jakearchibald.com/201... 作者用動(dòng)畫的形式非常形象清晰地描述了過程。

參考文章

The JavaScript Event Loop

JavaScript Event Loop Explained

EventLoop | MDN

Tasks, microtasks, queues and schedules

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

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

相關(guān)文章

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

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

    K_B_Z 評(píng)論0 收藏0
  • Javascript 運(yùn)行機(jī)制詳解,Event Loop

    摘要:主線程在任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷地,所以這種運(yùn)行機(jī)制叫做事件循環(huán)是在執(zhí)行棧同步代碼結(jié)束之后,下一次任務(wù)隊(duì)列執(zhí)行之前。 單線程 javascript為什么是單線程語言,原因在于如果是多線程,當(dāng)一個(gè)線程對(duì)DOM節(jié)點(diǎn)做添加內(nèi)容操作的時(shí)候,另一個(gè)線程要?jiǎng)h除這個(gè)DOM節(jié)點(diǎn),這個(gè)時(shí)候,瀏覽器應(yīng)該怎么選擇,這就造成了混亂,為了解決這類問題,在一開始的時(shí)候,javascript就采用單線...

    Jingbin_ 評(píng)論0 收藏0
  • 初窺JavaScript事件機(jī)制的實(shí)現(xiàn)(一)—— Node.js事件驅(qū)動(dòng)實(shí)現(xiàn)概覽

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

    lavor 評(píng)論0 收藏0
  • 瀏覽器與NodeJS的EventLoop異同,以及部分機(jī)制。

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

    jubincn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<