什么是事件循环?如何理解事件循环?事件循环原理如何描述?事件循环涉及了很多知识点,想要彻底掌握JS事件循环原理必须要掌握以下知识点:同步任务、异步任务、宏任务、微任务、任务队列、执行栈、js运行机制、EventLoop。
1.事件循环概念
事件循环就是js编译器解析与执行代码的规则。js本身是单线程,即同一时刻只能干一件事,而js任务包含了同步任务和异步任务,浏览器会率先执行同步代码,将异步代码放入消息队列(任务队列)中,待主线程任务完成后执行,而异步代码又分为宏任务和微任务,在同步代码全部执行完成后会先执行异步微任务再执行异步宏任务,如果异步任务中仍有异步任务,会继续放入消息队列(任务队列),以此类推,便形成了一个事件循环。(另外还需要分清楚事件循环是问的浏览器还是node的,两者不一样哦~此文)
2.宏任务和微任务
-
宏任务(macro task): 宏任务是由宿主环境(浏览器、Node)发起的,常见宏任务如下
setTimeout()
setInterval()
setImmediate()(Node.js 环境)
script( 整体代码)
I/O
UI 交互事件
特点:
(1) 不唯一,存在一定的优先级(用户I/O部分优先级更高)
(2) 异步执行,同一事件循环中,只执行一个 -
微任务(micro task): 微任务是由JS发起的任务,常见微任务如下:
promise.then()
promise.catch()
new MutaionObserver()
object.observe
Async/Await
process.nextTick()(Node.js 环境)
注:promise本身同步,then/catch的回调函数是异步的
特点:
(1) 唯一,整个事件循环当中,仅存在一个;
(2) 执行为同步,同一个事件循环中的microtask会按队列顺序,串行执行完毕;
3.小试牛刀
网上找个例子,一起练练手吧~
- 1
console.log('同步代码1');
setTimeout(() => {
console.log('setTimeout')
}, 0)
new Promise((resolve) => {
console.log('同步代码2')
resolve()
}).then(() => {
console.log('promise.then')
})
console.log('同步代码3');
// 最终输出"同步代码1"、"同步代码2"、"同步代码3"、"promise.then"、"setTimeout"
- 2
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
//答案:script start async1 start async2 promise1 script end async1 end promise2 setTimeout
注释:因为是前端面试题,所以答案是以浏览器的eventloop机制为准的,在node平台上运行会有差异!!!!