事件循环
- 同步任务和异步任务分别进入不同的线程,同步任务进入主线程,异步任务进入 Event Table 并注册函数(如果是 setTimeout 则开始计时)
- 指定任务完成时(获取到结果、计时完成)Event Table 会把对应的回调函数移入 Event Queue
- 主线程内的任务执行完毕后,会去 Event Queue 读取对应的函数,进入主线程执行 这个过程会不断重复,这就是事件循环
js 引擎存在 monitoring process 进程,会持续不断检查主线程执行栈是否为空,一旦为空就去 Event Queue 检查是否有待执行函数
宏任务和微任务
宏任务: 包括整体代码 script ,setTimeout,setInterval,setImmediate 微任务: 原生 Promise,promise.then(有些实现把 then 放到了宏任务中,这个我也不太明白),process.nextTick,MutationOberve
console.log('start'); // 输出
setTimeout(() => { // 放入宏任务 EventQueue
console.log('timeout1');
let p = new Promise(function(resolve, reject) {
console.log('promise3');
resolve('ok');
});
p.then((val) => {
console.log(val);
});
}, 0);
new Promise(function(resolve, reject) {
console.log('promise1'); // 执行
setTimeout(() => { // 放入宏任务 Event Queue
console.log('timeout2');
}, 0);
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
}).then(()=>{
console.log('then1');
});
resolve();
}).then(()=>{
console.log('then2');
});
console.log('end?');
执行顺序:
-
输出
start,将 setTimeout 放入宏任务的 Event Queue,输出promise1,将 setTimeout 放入宏任务的 Event Queue,输出promise2,把then1放入微任务的 Event Queue,把then2放入微任务的 Event Queue,输出end?主线程执行完毕,此时宏任务的 Event Queue 里面有 两个 setTimeout,微任务的 Event Queue 里有then1,then2,按照队列先进先出,所以先放入的先执行,输出then1,then2,微任务执行完毕,开始新的宏任务,即第一个setTimeout -
输出
timeout1,输出promise3,将ok放入微任务队列,执行微任务队列的任务,输出ok,此时宏任务 Event Queeu 中还有一个,微任务队列空了,开始下一个宏任务 -
输出
timeout2,至此所有任务执行完毕
**输出顺序为 start, promise1, promise2, end?, then1, then2, timeout1, promise3, ok, timeout2 **
最后,中间的有一个 undefined 看起来应该不是代码输出的,可能是某个函数的返回,暂时没有搞明白,对 Promise 理解还不够深入,记录一下