js執行順序Event Loop

sou發表於2018-03-27

javascript是一門單執行緒語言,為了實現主執行緒的不阻塞,但可以用Event Loop模擬多執行緒操作 Event Loop中同步非同步任務執行順序:

  • 所有非同步任務都是在Event Table中註冊函式,當指定的時間完成時,Event Table會將函式放入Event Queue,主執行緒的同步任務執行完會去Event Queue讀取對應函式,進入主執行緒執行。

image

js引擎monitoring process程式,當發現主程式執行棧為空,會去執行Event Queue中的函式

let data = [];
$.ajax({
    url:url
    data:data,
    success:() => {
        console.log('傳送成功!');
    }
})
console.log('程式碼執行結束');

複製程式碼

上面是ajax執行順序: ajax進入Event Table,註冊回撥函式success。 執行console.log('程式碼執行結束')。 ajax事件完成,回撥函式success進入Event Queue。 主執行緒從Event Queue讀取回撥函式success並執行。

除了廣義的同步任務和非同步任務,我們對任務有更精細的定義:

macro-task(巨集任務)::setTimeout、setInterval、setImmediate、I/O、UI互動事件 micro-task(微任務):Promise、process.nextTick、MutaionObserver

console.log('1');

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

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

複製程式碼

整段程式碼,共進行了三次事件迴圈,完整的輸出為1,7,6,8,2,4,3,5,9,11,10,12。 (請注意,node環境下的事件監聽依賴libuv與前端環境不完全相同,輸出順序可能會有誤差)

相關文章