js Event Loop
什么是Event Loop?
JavaScript 从 script
开始读取,然后不断循环,从 “任务队列” 中读取执行事件的过程,就是 事件循环(Event Loop)。
Event Loop的执行过程
1.一开始整个脚本 script
作为一个宏任务执行
2.执行过程中,同步代码 直接执行,宏任务 进入宏任务队列,微任务 进入微任务队列。
3.当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完毕。
4.执行浏览器 UI
线程的渲染工作。
5.检查是否有 Web Worker
任务,有则执行。 --------------------Web Worker 是运行在后台的 JS,独立于其他脚本,不会影响页面的性能。
6.执行完本轮的宏任务,回到步骤 2,依次循环,直到宏任务和微任务队列为空。
事件循环中的异步队列有两种:宏任务队列(MacroTask
)和 微任务队列(MicroTask
)。
宏任务队列可以有多个,微任务队列只有一个。
宏任务 包括:
script
setTimeout
setInterval
setImmediate
I/O
UI rendering
微任务 包括:
MutationObserver
Promise.then()/catch()
- 以
Promise
为基础开发的其他技术,例如fetch API
- V8 的垃圾回收过程
- Node 独有的
process.nextTick
实例1:定时器
console.log("1"); setTimeout(function () { console.log("2"); }, 0); setTimeout(function () { console.log("3"); }, 2000); console.log("4");
输出1 4 2 3
实例2:定时器+promise
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
输出:
script start
script end
promise1
promise2
setTimeout
实例3:综合1
setTimeout(function() { console.log(4); }, 0); const promise = new Promise((resolve) => { console.log(1); for (var i = 0; i < 10000; i++) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3);
输出:1 2 3 5 4
实例4:综合2
setTimeout(function () { console.log('timeout1'); }, 1000); console.log('start'); Promise.resolve().then(function () { console.log('promise1'); Promise.resolve().then(function () { console.log('promise2'); }); setTimeout(function () { Promise.resolve().then(function () { console.log('promise3'); }); console.log('timeout2') }, 0); }); console.log('done');
输出:
start
done
promise1
promise2
timeout2
promise3
timeout1