前端面试题 - - JavaScript中事件循环(eventloop)
这篇文章主要谈一谈对js中事件循环的理解?eventloop
一、事件循环:
js是单线程的,但是又需要一种机制来处理多个块的执行,并且执行每个块时都调用js引擎,这种机制称为事件循环,与事件绑定概念毫无关系
二、事件循环分为三部分:
主线程、宏队列、微队列,所有异步代码都会被丢进宏/微队列
2.1 主线程
所有的同步任务都是在主线程里执行的,异步任务可能会在微任务(macro task)或者宏任务(micro task)里面
- 同步任务: 指的是在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
- 异步任务: 指的是不进入主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
三、宏任务、微任务、执行过程
3.1、 JS把异步任务分为宏任务和微任务
在ES5之后,JavaScript引入了Promise,这样,不需要游览器,JavaScript引擎自身也能够发起异步任务。
3.1.1、同步代码(js执行/回调栈)
3.1.2微任务的异步代码(js引擎):
微任务是由JS发起的任务
- process.nextTick(node)
- promise.then() catch()
- Async/Await
- object.observe、MutaionOBserver
promise本身同步,then/catch的回调函数是异步的
3.1.3 宏任务的异步代码(宿主环境):
宏任务是由宿主环境(游览器、Node)发起
- script(代码块)
- setTimeout、setInterval,setImmeditate定时器
- I/O
- UI redering
3.2、主线程只有一个,且执行顺序为:
主线程代码☞☞ 微任务☞☞宏任务
如果宏任务里还有微任就继续执行宏任务里的微任务,如果宏任务中的微任务中还有宏任务就在依次进行
1.先执行主线程
2. 遇到宏任务放到宏队列
3. 遇到微任务放到微队列
4. 主线程执行完毕
5. 执行微队列,微队列执行完毕
6. 执行以一次宏队列的任务,执行完毕
7. 执行微队列,执行完毕
8. 依次循环
3.2.1、 简略
- 同步代码
- 微任务的异步代码(promise等)
- 宏任务的异步代码
面试题
示例1:
setTimeout(function(){
console.log('timeout1');
})
new Promise(function(resolve){
console.log('promise1');
for(var i =0; i <1000; i++) {
i ==99&& resolve();
}
console.log('promise2');
}).then(function(){
console.log('then1');
})
console.log('global1')
//打印的顺序
// promise1
// promise2
// global1
// then1timeout1
示例2:
setTimeout(function() {
console.log(4);
}, 0);
const promise = new Promise(function executor(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