eventloop 事件循环笔记
本文内容是学习以下2篇文章的笔记
https://juejin.im/post/5a6155126fb9a01cb64edb45
https://juejin.im/post/59e85eebf265da430d571f89
monitoring process进程不断检查主线程是否为空,为空的话就去执行Event Queue里面等待被调用的函数
settimeout(function() {
task();
},3)
sleep(1000000);
1.task进入EventTable并注册,计时开始
2.执行sleep,很慢,计时器仍在继续
3.3s到了,计时事件timeout完成,task进入Event Queue但是sleep还没完,继续等待
4.sleep执行完了,task进入主线程执行。
settimeout在指定时间后将要执行的任务加入Event Queue,又因为单线程任务要一个一个执行,如果前面的任务耗时太久就只能等着,导致延时超过3s。
settimeout(fn,0) 指定某个任务在主线程最早可得的空闲时间执行,意思是不用等多少秒了,主线程执行栈内所有同步任务全部执行完成了,栈为空就马上执行
ps:即使主线程为空,0ms也是达不到的,最低4ms (尚未验证)
setinterval(fn,ms)不是没过ms秒就会执行一次,而是没过ms秒将fn置入Event Queue,如果前面任务耗时太久仍需等待
注意:一旦回调fn的执行时间超过延迟时间,那么就完全看不出有时间间隔了
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
process.nextTick(fn) 类似于node版本的settimeout,在事件循环的下一次循环中调用fn回调函数
macro-task宏任务:整体代码script,settimeout,setinterval (new Promise也包括)
micro-task微任务:promise,process.nextTick
事件循环的顺序决定了js的执行顺序,进入整体代码(宏任务)后开始第一次循环,接着执行所有的微任务,然后再次从宏任务开始,找到其中一个队列执行完再执行所有的微任务
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.首先执行整体代码打印出 1 7
2.此时有2个宏任务set1,set2,2个微任务p1 then1,执行这两个微任务得到6 8
3.执行宏任务set1,得到2,4,执行与这个宏任务并列的微任务p2,then2得到3 5
4.执行宏任务set2,得到9,11,执行与这个宏任务并列的微任务p3,then3得到10 12
答案:1 7 6 8 2 4 3 5 9 11 10 12