javascript是一門單執行緒語言,為了實現主執行緒的不阻塞,但可以用Event Loop模擬多執行緒操作 Event Loop中同步非同步任務執行順序:
- 所有非同步任務都是在Event Table中註冊函式,當指定的時間完成時,Event Table會將函式放入Event Queue,主執行緒的同步任務執行完會去Event Queue讀取對應函式,進入主執行緒執行。
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與前端環境不完全相同,輸出順序可能會有誤差)