js的事件循环
事件循环
同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
当指定的事情完成时,Event Table会将这个函数移入Event Queue。
主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
上述过程会不断重复,也就是常说的Event Loop(事件循环)。
JS执行过程图原理图
宏任务(macro-task):
- 主线程代码(script中的代码)
- setTimeout
- setInterval
- setImmediate
- requestAnimationFrame
- I/O流
- UIrender(UI页面渲染)
- ajax请求
微任务(micro-task):
- process.nextTick
- Promise(准确来说是Promise的then(),catch ,finally)
- Async/Await(实际上就是promise)
- MutationObserver(html5新特性)
运行原则:
先同后异,先微后宏
例子1
setTimeout(() => {
console.log(1) //宏任务一
}, 20)
console.log(2)
setTimeout(() => {
console.log(3) //宏任务二
}, 10)
console.log(4)
// console.time("AA")
for (let i = 0; i < 90000000; i++) {
// ....
}
// console.timeEnd("AA") //=>AA:33ms 左右
console.log(5)
setTimeout(() => {
console.log(6) //宏任务三
}, 20)
console.log(7)
setTimeout(() => {
console.log(8) //宏任务四
}, 10)
//输出结果为 2 4 5 7 3 1 8 6
解析
1、先执行同步 所以输出的是2457
2、将setTimeout 放入宏任务 ,放入顺序如下:
在10ms 宏任务二
在20ms 放入宏任务一
又因为for 循环 33ms 所以 宏任务三和宏任务四的放置时间如下: (宏任务三和宏任务四是在for循环过后放入宏任务队列中 )
在43ms ( 33+10) 放入宏任务四
在53ms (33+20) 放入宏任务三
3、所以输入如下 24573186
例子2
async function async1() {
console.log("A");
await async2();
console.log("B");
}
async function async2() {
console.log("C");
}
console.log("D");
setTimeout(function () {
console.log("E");
}, 0);
async1();
new Promise(function (resolve) {
console.log("F");
resolve();
}).then(function () {
console.log("G");
});
console.log("H");
//输出 D A C F H B G E
解析:先同后异 先微后宏
// 解析 async 和await 是promise 的语法糖。 为了更加清楚了解async和await。 可以把 async1和async2 方法 转换
function async1() {
console.log("A");
new Promise(function (resolve) {
console.log("C"); //原来的 async2 中方法 同步的
resolve(); //异步
}).then(function () {
console.log("B");
});
}
// function async2() {
// console.log("C");
// }
例子3
const first = () => (new Promise((resolve,reject)=>{
console.log(3)
let p = new Promise((resolve,reject)=>{
console.log(7)
setTimeout(()=>{
console.log(5)
resolve(6)
},0)
resolve(1)
})
resolve(2)
p.then((arg)=>{
console.log(arg)
})
}))
first().then((arg)=>{
console.log(arg)
})
console.log(4)
//输出结果 374125
解析
例子4
setTimeout(()=>{
console.log("0")
},0)
new Promise((resolve,reject)=>{
console.log("1")
resolve()
}).then(()=>{
console.log("2")
new Promise((resolve,reject)=>{
console.log("3")
resolve()
}).then(()=>{
console.log("4")
}).then(()=>{
console.log("5")
})
}).then(()=>{
console.log("6")
})
new Promise((resolve,reject)=>{
console.log("7")
resolve()
}).then(()=>{
console.log("8")
})
结果:1 7 2 3 8 4 6 5 0
解析
参考:https://www.bilibili.com/video/BV1GV411s7G6?p=1&vd_source=f20aa366e643c372d2e9554d92277c4c(强烈推荐)
https://blog.csdn.net/weixin_48931875/article/details/121568586