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

資訊專欄INFORMATION COLUMN

JavaScript 異步、棧、事件循環(huán)、任務(wù)隊列

X_AirDu / 510人閱讀

摘要:引擎是單線程的,如上圖中,它負責(zé)維護任務(wù)隊列,并通過的機制,按順序把任務(wù)放入棧中執(zhí)行。接下來,我們會細說圖中的棧和任務(wù)隊列。直到微任務(wù)隊列為空,執(zhí)行下一步。上一輪循環(huán)中有少數(shù)的會被延遲到這一輪的這一階段執(zhí)行。

概覽


我們經(jīng)常會聽到引擎和runtime,它們的區(qū)別是什么呢?

引擎:解釋并編譯代碼,讓它變成能交給機器運行的代碼(runnable commands)。

runtime:就是運行環(huán)境,它提供一些對外接口供Js調(diào)用,以跟外界打交道,比如,瀏覽器環(huán)境、Node.js環(huán)境。不同的runtime,會提供不同的接口,比如,在 Node.js 環(huán)境中,我們可以通過 require 來引入模塊;而在瀏覽器中,我們有 window、 DOM。

Js引擎是單線程的,如上圖中,它負責(zé)維護任務(wù)隊列,并通過 Event Loop 的機制,按順序把任務(wù)放入棧中執(zhí)行。而圖中的異步處理模塊,就是 runtime 提供的,擁有和Js引擎互不干擾的線程。接下來,我們會細說圖中的:棧和任務(wù)隊列。

現(xiàn)在,我們要運行下面這段代碼:

function bar() {
    console.log(1);
}

function foo() {
    console.log(2);
    far();
}

setTimeout(() => {
    console.log(3)
});

foo();

它在棧中的入棧、出棧過程,如下圖:

任務(wù)隊列

Js 中,有兩類任務(wù)隊列:宏任務(wù)隊列(macro tasks)和微任務(wù)隊列(micro tasks)。宏任務(wù)隊列可以有多個,微任務(wù)隊列只有一個。那么什么任務(wù),會分到哪個隊列呢?

宏任務(wù):script(全局任務(wù)), setTimeout, setInterval, setImmediate, I/O, UI rendering.

微任務(wù):process.nextTick, Promise, Object.observer, MutationObserver.

瀏覽器的 Event Loop

瀏覽器的 Event Loop 遵循的是 HTML5 標(biāo)準(zhǔn),而 NodeJs 的 Event Loop 遵循的是 libuv。 區(qū)別較大,分開講。

我們上面講到,當(dāng)stack空的時候,就會從任務(wù)隊列中,取任務(wù)來執(zhí)行。瀏覽器這邊,共分3步:

取一個宏任務(wù)來執(zhí)行。執(zhí)行完畢后,下一步。

取一個微任務(wù)來執(zhí)行,執(zhí)行完畢后,再取一個微任務(wù)來執(zhí)行。直到微任務(wù)隊列為空,執(zhí)行下一步。

更新UI渲染。

Event Loop 會無限循環(huán)執(zhí)行上面3步,這就是Event Loop的主要控制邏輯。其中,第3步(更新UI渲染)會根據(jù)瀏覽器的邏輯,決定要不要馬上執(zhí)行更新。畢竟更新UI成本大,所以,一般都會比較長的時間間隔,執(zhí)行一次更新。

從執(zhí)行步驟來看,我們發(fā)現(xiàn)微任務(wù),受到了特殊待遇!我們代碼開始執(zhí)行都是從script(全局任務(wù))開始,所以,一旦我們的全局任務(wù)(屬于宏任務(wù))執(zhí)行完,就馬上執(zhí)行完整個微任務(wù)隊列??磦€例子:

console.log("script start");

// 微任務(wù)
Promise.resolve().then(() => {
    console.log("p 1");
});

// 宏任務(wù)
setTimeout(() => {
    console.log("setTimeout");
}, 0);

var s = new Date();
while(new Date() - s < 50); // 阻塞50ms

// 微任務(wù)
Promise.resolve().then(() => {
    console.log("p 2");
});

console.log("script ent");


/*** output ***/

// one macro task
script start
script ent

// all micro tasks
p 1
p 2

// one macro task again
setTimeout

上面之所以加50ms的阻塞,是因為 setTimeout 的 delayTime 最少是 4ms. 為了避免認為 setTimeout 是因為4ms的延遲而后面才被執(zhí)行的,我們加了50ms阻塞。

NodeJs 的 Event Loop

NodeJs 的運行是這樣的:

初始化 Event Loop

執(zhí)行您的主代碼。這里同樣,遇到異步處理,就會分配給對應(yīng)的隊列。直到主代碼執(zhí)行完畢。

執(zhí)行主代碼中出現(xiàn)的所有微任務(wù):先執(zhí)行完所有nextTick(),然后在執(zhí)行其它所有微任務(wù)。

開始 Event Loop

NodeJs 的 Event Loop 分6個階段執(zhí)行:

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

以上的6個階段,具體處理的任務(wù)如下:

timers: 這個階段執(zhí)行setTimeout()setInterval()設(shè)定的回調(diào)。

pending callbacks: 上一輪循環(huán)中有少數(shù)的 I/O callback 會被延遲到這一輪的這一階段執(zhí)行。

idle, prepare: 僅內(nèi)部使用。

poll: 執(zhí)行 I/O callback,在適當(dāng)?shù)臈l件下會阻塞在這個階段

check: 執(zhí)行setImmediate()設(shè)定的回調(diào)。

close callbacks: 執(zhí)行比如socket.on("close", ...)的回調(diào)。

每個階段執(zhí)行完畢后,都會執(zhí)行所有微任務(wù)(先 nextTick,后其它),然后再進入下一個階段。

Links

Event loops

NodeJs 的 Event Loop 官方文檔

并發(fā)模型與事件循環(huán)

Philip Roberts: Help, I’m stuck in an event-loop.

Promise的隊列與setTimeout的隊列有何關(guān)聯(lián)?

JavaScript:徹底理解同步、異步和事件循環(huán)(Event Loop)

從event loop規(guī)范探究javaScript異步及瀏覽器更新渲染時機

JavaScript 運行機制詳解:再談Event Loop - 阮一峰的網(wǎng)絡(luò)日志

Tasks, microtasks, queues and schedules

WindowOrWorkerGlobalScope.setTimeout()

What is the difference between JavaScript Engine and JavaScript Runtime Environment

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

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

相關(guān)文章

  • JavaScript運行機制和事件循環(huán)

    摘要:主線程不斷重復(fù)上面的三步,此過程也就是常說的事件循環(huán)。所以主線程代碼執(zhí)行時間過長,會阻塞事件循環(huán)的執(zhí)行。參考資料這一次,徹底弄懂執(zhí)行機制任務(wù)隊列的順序機制事件循環(huán)搞懂異步事件輪詢與中的事件循環(huán) 1. 說明 讀過本文章后,您能知道: JavaScript代碼在瀏覽器中的執(zhí)行機制和事件循環(huán) 面試中經(jīng)常遇到的代碼輸出順序問題 首先通過一段代碼來驗證你是否了解代碼輸出順序,如果你不知道輸出...

    Ververica 評論0 收藏0
  • 總結(jié):JavaScript異步事件循環(huán)與消息隊列、微任務(wù)與宏任務(wù)

    摘要:單線程異步非阻塞然后,這又牽扯到了事件循環(huán)消息隊列,還有微任務(wù)宏任務(wù)這些。此步的位置不確定某個時刻后,定時器觸發(fā)線程通知事件觸發(fā)線程,事件觸發(fā)線程將回調(diào)函數(shù)加入消息隊列隊尾,等待引擎線程執(zhí)行。 前言 Philip Roberts 在演講 great talk at JSConf on the event loop 中說:要是用一句話來形容 JavaScript,我可能會這樣: Java...

    qianfeng 評論0 收藏0
  • 理解異步JavaScript

    摘要:當(dāng)函數(shù)結(jié)束,將會被從調(diào)用棧移出。事件循環(huán)事件循環(huán)的責(zé)任就是查看調(diào)用棧并確定調(diào)用棧是否為空。事件循環(huán)會再次檢查調(diào)用棧是否為空,如果為空的話,它會把事件回調(diào)壓入棧中,然后回調(diào)函數(shù)則被執(zhí)行。 寫在文章前 這篇文章是翻譯自Sukhjinder Arora的Understanding Asynchronous JavaScript。這篇文章描述了異步和同步JavaScript是如何在運行環(huán)境中,...

    ixlei 評論0 收藏0
  • 大話javascript 4期:事件循環(huán)(2)

    摘要:只要指定過回調(diào)函數(shù),這些事件發(fā)生時就會進入任務(wù)隊列,等待主線程讀取。三主線程從任務(wù)隊列中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為事件循環(huán)。 一、任務(wù)隊列 同步任務(wù)與異步任務(wù)的由來 單線程就意味著,所有任務(wù)需要排隊,前一個任務(wù)結(jié)束,才會執(zhí)行后一個任務(wù)。如果前一個任務(wù)耗時很長,后一個任務(wù)就不得不一直等著。 如果排隊是因為計算量大,CPU忙不過來,倒也算了,但是很多時候C...

    李昌杰 評論0 收藏0
  • JavaScript事件循環(huán)

    摘要:事件循環(huán)當(dāng)主線程中的任務(wù)執(zhí)行完畢后,會從任務(wù)隊列中獲取任務(wù)一個個的放在棧中執(zhí)行去執(zhí)行,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為事件循環(huán)。 寫在前面 說起javascript(以下簡稱js)這門語言,相信大家已經(jīng)非常熟悉了,不管是前端開發(fā)還是后端開發(fā)幾乎無時無刻都要跟它打交道。雖說開發(fā)者每天幾乎都要操作js,但是你真的確定你掌握了js的運行機制嗎!下面我們就來聊聊這話題。 Ja...

    Corwien 評論0 收藏0
  • Javascript系列之javascript機制

    摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊列回到執(zhí)行棧,回調(diào)函數(shù)就會執(zhí)行。事件循環(huán)主線程從任務(wù)隊列中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機制https://zhuanlan.zhihu.com/p/...從瀏覽器多進程到JS單線程,JS運行機制...

    13651657101 評論0 收藏0

發(fā)表評論

0條評論

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