JavaScript 中的工作佇列與Promise
在 JS 中,“事件迴圈(Event Loop)”的概念相信大家都不陌生。在 ES6 中,在事件迴圈佇列之上引入了一層新概念,稱為“工作佇列(Job queue)”,這個概念在 Promise 的非同步行為中有用到。恰好在網上看到一篇文章,通過一小段程式對這兩個概念進行了展示,對我很有幫助,分享給大家。注意以下並非對原文的逐字翻譯。
預備知識:
- 事件迴圈(Event Loop)(參見《你不知道的 JavaScript (中卷) 》第一章)
- 工作佇列(Job Queue)(參見《你不知道的 JavaScript (中卷) 》第一章)
- 在 Promise 上呼叫
then(..)
的時候,提供給then(..)
的回撥函式總是被非同步呼叫(排程到工作佇列中),即使 Promise 已經被解析了。 setTimeout(..)
中的回撥函式也總是被非同步呼叫,不過是安排在了事件迴圈的下一個 tick 中。
示例:
const p = new Promise(
// this is called the "executor"
(resolve, reject) => {
console.log(1);
resolve(2);
console.log(3);result
}
);
console.log(4);
p.then(
// this is called the success handler
result => console.log(result)
);
setTimeout(() => console.log(5), 0);
console.log(6);
上面程式碼的輸出結果是 1 3 4 6 2 5
。
解釋
第一步:Executor
Executor (見程式碼註釋)總是被立即執行。當新建立 Promise 的時候,傳給構造器的函式總是在當前 tick 中立馬執行。所以 1
被列印出來, resolve
函式被呼叫,Promise 被解析,之後沒有觸發新的事件。然後 3
被列印。當前 tick 繼續往下走,跳出 Promise 的建構函式,列印出 4
。
第二步: .then
接下來執行 .then(..)
。Promise p
已經被解析,處理成功狀態的回撥函式會被排程到工作佇列中執行。
第三步: 工作佇列
事件迴圈中的每一個 tick 都會擁有自己的工作佇列(Job Queue),工作佇列中的資訊會在當前 tick 的末尾,下一個 tick 之前被處理,所以此時 result(=2)
不會被列印。
第四步:事件迴圈佇列
setTimeout(..)
和事件監聽中的回撥函式會被排程到事件迴圈佇列中,即便是延遲時間為 0
。
第五步:接下來
.then
與 setTimeout(..)
語句分別被排程到工作佇列和事件迴圈佇列中,二者都會非同步執行。當前 tick 繼續前進,列印出 6
。
然而當前 tick
並沒有結束,因為工作佇列中依然有事件需要處理。接下來程式會執行被排程到工作佇列中處理成功狀態的回撥函式,輸出 2
。此時佇列中已經沒有其他事件,當前 tick 結束。
接下來程式進入下一個 tick ,5
被輸出,整個程式結束。
走完這個例子,相信大家對事件迴圈及工作佇列的概念和 Promise 的運作機制,有了更加深入的理解。 (完)
參考資料:
《你不知道的 JavaScript (中卷) 》第1章和第3章
http://www.reactjunkie.com/promises-promises/
相關文章
- synchronized 中的同步佇列與等待佇列synchronized佇列
- 用JavaScript實現棧與佇列JavaScript佇列
- 執行緒池與工作佇列(轉)執行緒佇列
- 同步容器、併發容器、阻塞佇列、雙端佇列與工作密取佇列
- 基於promise的阻塞式佇列設計Promise佇列
- Laravel RabbitMQ 工作佇列LaravelMQ佇列
- libuv工作佇列佇列
- RabbitMQ的工作佇列和路由MQ佇列路由
- linux下的工作佇列Linux佇列
- 阻塞佇列一——java中的阻塞佇列佇列Java
- javascript實現佇列JavaScript佇列
- JavaScript 中如何實現函式佇列?(一)JavaScript函式佇列
- JavaScript中的Promise小結JavaScriptPromise
- 細說 JavaScript 中的 PromiseJavaScriptPromise
- Stack and Queue in JavaScript(Javascript中的資料結構之棧和佇列)JavaScript資料結構佇列
- RabbitMQ 入門 - 工作佇列MQ佇列
- javascript資料結構與演算法-佇列JavaScript資料結構演算法佇列
- javascript資料結構與演算法---佇列JavaScript資料結構演算法佇列
- javascript非同步與promiseJavaScript非同步Promise
- Java中的阻塞佇列Java佇列
- Java 中佇列的使用Java佇列
- 資料結構與演算法JavaScript (二) :佇列資料結構演算法JavaScript佇列
- JavaScript中async和await的使用以及佇列問題JavaScriptAI佇列
- [JavaScript] Promise 與 Ajax/AxiosJavaScriptPromiseiOS
- Linux核心中的軟中斷、tasklet和工作佇列詳解Linux佇列
- 聊一聊Javascript中的Promise物件JavaScriptPromise物件
- java 棧與佇列Java佇列
- JavaScript的資料結構與演算法(一)——棧和佇列JavaScript資料結構演算法佇列
- 訊息佇列中的Oracle佇列Oracle
- 稀疏陣列、佇列的概念與實踐陣列佇列
- JavaScript資料結構之-佇列JavaScript資料結構佇列
- JavaScript資料結構03 – 佇列JavaScript資料結構佇列
- JavaScript資料結構之佇列JavaScript資料結構佇列
- JavaScript資料結構03 - 佇列JavaScript資料結構佇列
- JavaScript 非同步與 Promise 實現JavaScript非同步Promise
- JavaScript資料結構之陣列棧佇列JavaScript資料結構陣列佇列
- 02Javascript資料結構與演算法 之 佇列JavaScript資料結構演算法佇列
- java執行緒池-工作佇列workQueueJava執行緒佇列