什么是事件循环?
- 事件循环可以理解成:JavaScript和浏览器或者Node之间的一个桥梁。
- 浏览器的事件循环是一个我们编写的JavaScript代码和浏览器API调用(setTimeout/AJAX/监听事件等)的一个桥梁, 桥梁之间他们通过回调函数进行沟通。
- Node的事件循环是一个我们编写的JavaScript代码和系统调用(file system、network等)之间的一个桥梁, 桥梁之间他们通过回调函数进行沟通。
要了解事件循环的话,进程和线程也是非常需要弄清楚的
进程(process):计算机已经运行的程序;
线程(thread):操作系统能够运行运算调度的最小单位
形象的来说就是:操作系统类似于一个工厂,工厂中里有很多车间,这个车间就是进程,每个车间可能有一个以上的工人在工厂,这个工人就是线程
众所周知,JavaScrip是单线程的
- 但是,浏览器或者node是多线程的
那么,浏览器的事件循环是怎么样的呢?
js 执行的时候会判断当前代码是同步还是异步,同步就进入同步消息队列中立即执行,异步就推进异步消息队列中等待执行
浏览器是多线程的,异步消息队列中的异步任务会被分配线程去执行
当所有同步任务执行完毕后,主线程空闲下来就会去到异步消息队列中看是否有异步任务达到可执行状态,然后就将其推到同步消息队列中去执行
异步任务分为微任务和宏任务
在执行每个宏任务前,都会先检查有没有微任务,有的话微任务先执行
微任务:Promise的then回调 、async/await、Mutation Observer API、queueMicrotask()
宏任务:ajax、setTimeout、setInterval、DOM监听
setTimeout(function () {
console.log("set1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then4");
});
console.log("then2");
});
});
new Promise(function (resolve) {
console.log("pr1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("set2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask1")
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
/*
pr1
2
then1
queueMicrotask1
then3
set1
then2
then4
set2
*/