前言
本文僅以記錄瀏覽器環境的event loop 和 node環境中的event loop的瞭解過程,若是錯誤,歡迎指正
瀏覽器環境
Event Loop是指在js執行環境中存在主執行線程和任務隊列(Task Queue),其中全部同步任務都在主執行線程中造成一個執行棧,全部異步任務都會放到任務隊列中
具體執行過程:
1. 主線程執行同步任務, 在主線程執行的過程當中,不斷行程堆棧並執行出棧入棧的操做
2. 若是主線程任務沒有完成,繼續完成,若是完成了就執行下一步
3. 系統讀取隊列任務, 開始執行
4. 不斷循環
而咱們的異步任務中,分爲宏任務(macrotask) 和微任務(microtask),
執行順序
1. 先取出macrotask任務隊列中的第一個任務進行執行
2. 取出Macrotask Queue中一個任務執行。
3. 取出Microtask Queue中任務執行直到清空。
node
執行任務爲:
1. timers 階段: 這個階段執行setTimeout和setInterval預約的callback;
2. I/O callbacks 階段: 執行除了 close事件的callbacks、被timers設定的callbacks、setImmediate()設定的callbacks這些以外的callbacks;
3. idle, prepare 階段: 僅node內部使用;
4. poll 階段: 獲取新的I/O事件, 適當的條件下node將阻塞在這裏;
5. check 階段: 執行setImmediate() 設定的callbacks;
6. close callbacks 階段: 執行socket.on('close', ...)這些 callback
![](http://static.javashuo.com/static/loading.gif)
參考文檔,對比 setImmediate 和 process.nextTick()
setImmediate 和 process.nextTick()
setImmediate(() => console.log('immediate1'));
setImmediate(() => console.log('immediate2'));
setTimeout(() => console.log('setTimeout1'), 1000);
setTimeout(() => {
console.log('setTimeout2');
process.nextTick(() => console.log('nextTick1'));
}, 0);
setTimeout(() => console.log('setTimeout3'), 0);
process.nextTick(() => console.log('nextTick2'));
process.nextTick(() => {
process.nextTick(console.log.bind(console, 'nextTick3'));
});
process.nextTick(() => console.log('nextTick4'));
複製代碼
執行結果:
在控制檯中執行node index.js,獲得的結果以下:
nextTick2
nextTick4
nextTick3
setTimeout2
setTimeout3
nextTick1
immediate1
immediate2
setTimeout1
複製代碼
結論
在node中,nextTick的優先級高於setTimeout和setImmediate(),因此會先執行nextTick裏面的信息打印。
可是對於嵌套的nextTick,會慢於同步的nextTick,因此nextTick4會先於nextTick3
而後開始一個Event Loop過程,首先執行timer階段,而此時setTimeout所須要等待的時間是0,因此當即執行setTimeout2和setTimeout3裏面的邏輯。而setTimeout1因爲設置了執行時間,不知足執行條件,被放到下一輪Event Loop
當前Event Loop執行到check階段,因而打印出immediate一、immediate2
執行後面的Event Loop,當setTimeout1達到執行條件時執行
基於node事件的event loop,咱們使用事件也變得方便快捷
event.emit('eventType', () => {})
event.on('eventType', () => {})