javascript
JavaScript event loop事件循环 macrotask与microtask
macrotask??姑且稱為宏任務,在很多上下文也被簡稱為task。例如:
?
?setTimeout,
setInterval,
setImmediate,
I/O,
UI rendering.
?
microtask?微任務,也稱job。例如:
process.nextTick,
Promise(原生),
Object.observe,
MutationObserver
備注:同時需要注意的是,在 ES 當中稱 microtask 為 “jobs”。比如?ES6標準?8.4節當中的 “EnqueueJob” 意思指添加一個 microtask。
?
?
?
看看下面的實例:
setImmediate(function(){console.log(1); },0); setTimeout(function(){console.log(2); },0); new Promise(function(resolve){console.log(3);resolve();console.log(4); }).then(function(){console.log(5); }); console.log(6); process.nextTick(function(){console.log(7); }); console.log(8);//輸出結果是3 4 6 8 7 5 2 1?
看看另一題目
setTimeout(()=>{console.log('A'); },0); var obj={func:function () {setTimeout(function () {console.log('B')},0);return new Promise(function (resolve) {console.log('C');resolve();})} }; obj.func().then(function () {console.log('D') }); console.log('E');
1、首先?setTimeout?A 被加入到事件隊列中? ==>? 此時macrotasks中有[‘A’];
2、obj.func()執行時,setTimeout B 被加入到事件隊列中? ==> 此時macrotasks中有[‘A’,‘B’];
3、接著return一個Promise對象,Promise 新建后立即執行 執行console.log('C'); 控制臺首次打印‘C’;
4、然后,then方法指定的回調函數,被加入到microtasks隊列,將在當前腳本所有同步任務執行完才會執行。 ==> 此時microtasks中有[‘D’];
5、然后繼續執行當前腳本的同步任務,故控制臺第二次輸出‘E’;
6、此時所有同步任務執行完畢,如上所述先檢查microtasks隊列,完成其中所有任務,故控制臺第三次輸出‘D’;
7、最后再執行macrotask的任務,并且按照入隊列的時間順序,控制臺第四次輸出‘A’,控制臺第五次輸出‘B’。
結果 C? E? D A B
?
?
?
setTimeout(function timeout () {console.log('timeout');},0);setImmediate(function immediate () {console.log('immediate');});結果
immediate
?timeout
?
?
setInterval(function timeout () {console.log('setInterval');},0);setTimeout(function timeout () {console.log('timeout');},0);setImmediate(function immediate () {console.log('immediate');});結果:
immediate
?setInterval
?timeout
?setInterval??
?
setTimeout(function timeout () {console.log('timeout');},0);setInterval(function timeout () {console.log('setInterval');},0);
timeout
setInterval
?
另一個
setTimeout(function timeout () {console.log('timeout'); },0);setImmediate(function immediate () {console.log('immediate'); });process.nextTick(function immediate () {console.log('nickTick'); });結果
nextTick timeout immediateprocess.nextTick像是一個插入的tick. 生成了一個新的周期. 說白了, 是一個插隊行為.
關于micro-task和macro-task的執行順序,可看下面這個例子(來自《深入淺出Node.js》): //加入兩個nextTick的回調函數 process.nextTick(function () {console.log('nextTick延遲執行1'); }); process.nextTick(function () { console.log('nextTick延遲執行2'); }); // 加入兩個setImmediate()的回調函數 setImmediate(function () {console.log('setImmediate延遲執行1'); // 進入下次循環 process.nextTick(function () {console.log('強勢插入');}); }); setImmediate(function () {console.log('setImmediate延遲執行2'); });console.log('正常執行')
書中給出的執行結果是:
正常執行 nextTick延遲執行1 nextTick延遲執行2 setImmediate延遲執行1 強勢插入 setImmediate延遲執行2?
process.nextTick在兩個setImmediate之間強行插入了。
但運行這段代碼發現結果卻是這樣:
樸老師寫那本書的時候,node最新版本為0.10.13,而我的版本是6.x
?轉載于:https://www.cnblogs.com/surfaces/p/10736151.html
總結
以上是生活随笔為你收集整理的JavaScript event loop事件循环 macrotask与microtask的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux下ifconfig命令看不到I
- 下一篇: 批量插入以及数据存在重复就进行更新操作