浏览器的事件循环机制
由来: js是单线程(一次只能进行一下操作)的语言,主要是用于页面和用户之间的交互,因为如果是多线程在渲染的时候是会出现问题的,比如同时对一个dom进行输入和删除的操作,此时就会产生冲突,但是单线程没有多线程处理方法的话,也会有问题,比如ajax请求数据/定时器/事件绑定等,此时一直在等待服务器返回数据界面,出现阻塞,用户的体验感也会不好,效率也会很低,因此就产生了一些单线程中的异步操作。
异步操作
事件(同步任务、宏任务和微任务)
-
同步任务(MainTask):JavaScript按照正常顺序执行的代码。 例如:函数调用,数值运算等等,特点就是执行后立即可以得到结果。 -
宏任务(MacroTask):setTimeout、setInterval、I/O、UI渲染。 -
微任务(MicroTask):Promise、Object.obsever、MutationObsever用户交互事件( User Interaction Event):点击事件 onclick 、键盘事件 onkeydown 、鼠标事件 onmouseover 等等
执行的顺序
具体流程:
- 执行完主逻辑中的同步任务
- 取出微任务队列(MicroTask Queue)中的任务执行,直到队列被完全清空然后取出宏任务队列(MacroTask Queue)中的一个任务执行。
- 执行完了一个宏任务后取出微任务队列(MicroTask Queue)中的任务执行,直到队列被完全清空,重复 这个和 上一个,直到宏任务队列(MacroTask Queue)被清空。
举例
console.log('1');
setTimeout(function() {
console.log('2');
new Promise(function(resolve) {
console.log('3');
resolve();
}).then(function() {
console.log('4')
})
},0)
new Promise(function(resolve) {
console.log('5');
resolve();
}).then(function() {
console.log('6')
})
setTimeout(function() {
console.log('7');
new Promise(function(resolve) {
console.log('8');
resolve();
}).then(function() {
console.log('9')
})
console.log('10')
},0)
console.log('11')
async function async1() {
console.log('1');
await async2();
console.log('2');
}
async function async2() {
console.log('3');
}
console.log('4');
setTimeout(function() {
console.log('5');
}, 0)
async1();
new Promise(function(resolve) {
console.log('6');
resolve();
}).then(function() {
console.log('7');
});
console.log('8');
|