摘要:簡要介紹談談在隊列中的執行順序問題的來源都不陌生,是指主線程從任務隊列中循環讀取任務,比如例輸出在上述的例子中,我們明白首先執行主線程中的同步任務,當主線程任務執行完畢后,再從中讀取任務,因此先輸出,再輸出。
簡要介紹:談談promise.resove,setTimeout,setImmediate,process.nextTick在EvenLoop隊列中的執行順序
問題的來源event loop都不陌生,是指主線程從“任務隊列”中循環讀取任務,比如
例1: setTimeout(function(){console.log(1)},0); console.log(2) //輸出2,1
在上述的例子中,我們明白首先執行主線程中的同步任務,當主線程任務執行完畢后,再從event loop中讀取任務,因此先輸出2,再輸出1。
event loop讀取任務的先后順序,取決于任務隊列(Job queue)中對于不同任務讀取規則的限定。比如下面一個例子:
例2: setTimeout(function () { console.log(3); }, 0); Promise.resolve().then(function () { console.log(2); }); console.log(1); //輸出為 1 2 3
先輸出1,沒有問題,因為是同步任務在主線程中優先執行,這里的問題是setTimeout和Promise.then任務的執行優先級是如何定義的。
執行順序在Job queue中的隊列分為兩種類型:macro-task和microTask。我們舉例來看執行順序的規定,我們設
macro-task隊列包含任務: a1, a2 , a3 micro-task隊列包含任務: b1, b2 , b3
執行順序為,首先執行marco-task隊列開頭的任務,也就是 a1 (a1代表同步的主任務)任務,執行完畢后,在執行micro-task隊列里的所有任務,也就是依次執行b1, b2 , b3(異步),執行完后清空micro-task中的任務,接著執行marco-task中的第二個任務(異步),依次循環。
了解完了macro-task和micro-task兩種隊列的執行順序之后,我們接著來看,真實場景下這兩種類型的隊列里真正包含的任務(我們以node V8引擎為例),在node V8中,這兩種類型的真實任務順序如下所示:
macro-task隊列真實包含任務:
script(主程序代碼)[對應上方的a1],setTimeout, setInterval, setImmediate, I/O, UI rendering
micro-task隊列真實包含任務:
process.nextTick, Promises, Object.observe, MutationObserver
由此我們得到的執行順序應該為:
script(主程序代碼)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering
在ES6中macro-task隊列又稱為ScriptJobs,而micro-task又稱PromiseJobs
舉例(1) setTimeout和promise
例3: setTimeout(function () { console.log(3); }, 0); Promise.resolve().then(function () { console.log(2); }); console.log(1);
(2) process.nextTick和promise、setTimeout
例子4: setTimeout(function(){console.log(1)},0); new Promise(function(resolve,reject){ console.log(2); resolve(); }).then(function(){console.log(3) }).then(function(){console.log(4)}); process.nextTick(function(){console.log(5)}); console.log(6); //輸出2,6,5,3,4,1
(3)更復雜的例子
setTimeout(function(){console.log(1)},0); new Promise(function(resolve,reject){ console.log(2); setTimeout(function(){resolve()},0) }).then(function(){console.log(3) }).then(function(){console.log(4)}); process.nextTick(function(){console.log(5)}); console.log(6); //輸出的是 2 6 5 1 3 4
這些例子的原因請根據執行順序執行判斷,這里不一一解釋了
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98755.html
摘要:如果沒到毫秒,那么階段就會跳過,進入階段,先執行的回調函數。參考文檔什么是瀏覽器的事件循環不要混淆和瀏覽器中的定時器詳解瀏覽器和不同的事件循環深入理解事件循環機制篇中的執行機制 最近對Event loop比較感興趣,所以了解了一下。但是發現整個Event loop盡管有很多篇文章,但是沒有一篇可以看完就對它所有內容都了解的文章。大部分的文章都只闡述了瀏覽器或者Node二者之一,沒有對比...
摘要:深入理解引擎的執行機制靈魂三問為什么是單線程的為什么需要異步單線程又是如何實現異步的呢中的中的說說首先請牢記點是單線程語言的是的執行機制。 深入理解JS引擎的執行機制 1.靈魂三問 : JS為什么是單線程的? 為什么需要異步? 單線程又是如何實現異步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.說說setTimeout 首先,請牢記2...
摘要:瀏覽器與的異同,以及部分機制有人對部分迷惑,本身構造函數是同步的,是異步。瀏覽器的的已全部分析完成,過程中引用阮一峰博客,知乎,部分文章內容,侵刪。 瀏覽器與NodeJS的EventLoop異同,以及部分機制 PS:有人對promise部分迷惑,Promise本身構造函數是同步的,.then是異步。---- 2018/7/6 22:35修改 javascript 是一門單線程的腳本...
摘要:瀏覽器和中并不一樣,瀏覽器的是在中定義的規范,而中則由庫實現。整個的這種運行機制又稱為事件循環例子了解瀏覽器的后,查看下面例子,猜測瀏覽器是怎么輸出的瀏覽器輸出中的在內部有這樣一個事件環機制。在啟動時會初始化事件環。執行和中到期的。 大家都知道,javascript是一門單線程語言,因此為了實現主線程的不阻塞,Event Loop這樣的方案應運而生。 瀏覽器和node中Event lo...
閱讀 2637·2023-04-26 02:17
閱讀 1610·2021-11-24 09:39
閱讀 1070·2021-11-18 13:13
閱讀 2598·2021-09-02 15:11
閱讀 2770·2019-08-30 15:48
閱讀 3406·2019-08-30 14:00
閱讀 2431·2019-08-29 13:43
閱讀 658·2019-08-29 13:07