Javascript 事件循環event loop

都知道javascript是單線程,那麼問題來了,既然是單線程順序執行,那怎麼作到異步的呢?javascript

咱們理解的單線程應該是這樣的,排着一個個來,是同步執行。

in-the-queue.jpg

現實中js是這樣的

setTimeout(function() {
            console.log(1);
        });
        new Promise(function(resolve, reject) {
            console.log(2)
            resolve(3)
        }).then(function(val) {
            console.log(val);
        })
        console.log(4)
        //執行結果爲 二、四、三、1

結果告訴咱們,js是單線程沒錯,不過不是逐行同步執行。java

那咱們就來解析一下既然有異步,那順序是怎樣的?這些執行順序規則就是理解eventLoop的要點,繼續往下。node

Kapture 2019-01-15 at 16.01.35.gif

上圖爲我錄製的chrome控制代碼臺執行順序,雖然能看出執行順序但咱們仍是懵逼的,咱們不知道規則,不懂就要問。ajax

搜索了不少官方、我的博客獲得了一堆詞:js引擎、主線程、事件表、事件隊列、宏任務、微任務,完全懵逼。。。chrome

不急不急一個個來,咱們進入刨根問底狀態segmentfault

js引擎

總結一句話就是解析優化代碼 **制定執行規則 具體規則往下看瀏覽器

主線程

總結一句話執行js引擎優化並排列順序後的代碼異步

事件表(event table)

執行代碼過程當中,異步的回調,例如(setTimeout,ajax回調)註冊回調事件到event table函數

事件隊列

當事件回調結束,事件表(event table)會將事件移入到事件隊列(event queue)oop

宏任務和微任務

宏任務包含的事件
事件 瀏覽器 node
I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame
微任務包含的事件
事件 瀏覽器 node
I/O
process.nextTick
MutationObserver
Promise.then catch finally

不少博客是這樣說的:
瀏覽器會不斷從task隊列中按順序取task執行,每執行完一個task都會檢查microtask隊列是否爲空(執行完一個task的具體標誌是函數執行棧爲空),若是不爲空則會一次性執行完全部microtask。而後再進入下一個循環去task隊列中取下一個task執行

說實話不是太理解,那麼我就以本身的方式去學習和理解

爲了更好的理解咱們再看代碼

console.log('1');
        setTimeout(function() {
            console.log('2');
            new Promise(function(resolve) {
                console.log('3');
                resolve();
            }).then(function() {
                console.log('4')
            })
        })
        new Promise(function(resolve) {
            console.log('5');
            resolve();
        }).then(function() {
            console.log('6')
        })

        setTimeout(function() {
            console.log('7');
            new Promise(function(resolve) {
                console.log('8');
                resolve();
            }).then(function() {
                console.log('9')
            })
        })
        //執行結果:一、五、六、二、三、四、七、八、9

image.png
有圖爲證我沒騙你
再來個動圖咱們具體看看瀏覽器的執行順序
eventLoop1.gif

首先js引擎,區分是直接執行(同步代碼),再執行異步代碼,若是是異步再區分是宏任務仍是微任務,分別放入兩個任務隊列,而後開始執行,每執行完一個宏任務,掃一遍微任務隊列並所有執行,此時造成一次eventLoop循環。以此規則不停的執行下去就是咱們所聽到的事件循環。

我再補充一點,能夠理解js引擎一開始把整個script當作一個宏任務,這樣裏邊的就更容易理解了,開始就執行script宏任務,解析到宏任務裏邊又包含同步代碼和異步代碼(宏任務和微任務)依次執行順序造成eventLoop。

歡迎吐槽點贊評論!

文章參考學習:
https://www.jianshu.com/p/12b...
https://juejin.im/post/59e85e...
https://segmentfault.com/a/11...

相關文章
相關標籤/搜索