1、什么是js运行机制
js运行机制,也就是事件循环机制。js是单线程执行的,同一时间只能做一件事,但并不是说单线程就会阻塞,要实现单线程且非阻塞的方法就是事件循环机制。在js中,会把任务分为同步和异步,这两者的执行环境不同,同步任务会进入主线程,异步任务会进入事件队列,当主线程代码执行完毕后,会去事件队列中读取对应的异步任务,并推到主线程中执行,不断重复的过程,就称为事件循环机制。
2、js的任务分类
js中将任务分为同步任务和异步任务两大类
同步任务:只要被系统扫描到,就会被主线程马上执行的任务(优先于所有的异步任务)
异步任务:即使被扫描到,也不会马上执行,会被放到事件队列中,等主线程任务执行完毕,系统才会召回执行
常见的异步任务
1、Promise.then() === 微任务
2、async/await === Promise语法糖 === 微任务
3、事件处理函数
4、setTimeout() 和 setInterval() === 宏任务
3、异步任务分类
异步任务又被称为宏任务和微任务
在异步任务中,有些异步任务的平均执行周期很长,这些任务就被js标记为宏任务(比如延时器setTimeout()), 而平均执行周期相对较短的任务,被称为微任务(如promise.then())
4、异步任务的执行顺序
1、会优先执行已经存在于任务队列中的微任务
2、在所有微任务执行完成后,再去执行一个宏任务(只执行一个)
3、执行完宏任务,会再去微任务队列查找是否有新的微任务,有的话就全部执行
4、再回到宏任务队列执行一个宏任务
5、依次循环,整个流程就是事件循环机制
5、例题分析
setTimeout(() => {
console.log("1")
}, 0) //异步任务 - 宏任务
console.log(2) //同步任务
Promise.resolve().then(() => {
console.log(3)
}) //异步任务 - 微任务
console.log(6) //同步任务
// 打印结果 2 6 3 1
分析:代码执行顺序: 先执行同步任务打印2和6,然后进入异步队列,异步中先执行微任务打印3,最后执行宏任务打印1
//第一个宏任务
setTimeout(() => {
console.log(1) //宏任务中的同步任务
Promise.resolve().then(() => {
console.log(7)
}) //宏任务中的微任务
}, 0) //异步任务 - 宏任务
console.log(2) //同步任务
Promise.resolve().then(() => {
console.log(3)
}) //异步任务 - 微任务
//第二个宏任务
setTimeout(() => {
console.log(8) //宏任务中的同步任务
setTimeout(() => {
console.log(5)
}, 0) //宏任务中的宏任务 第四个宏任务
}, 0)
//第三个宏任务
setTimeout(() => {
Promise.resolve().then(() => {
console.log(4)
}) //宏任务中的微任务
}, 0)
console.log(6) //同步任务
// 2 6 3 1 7 8 4 5
分析:
先执行同步任务打印2和6
再去执行异步,异步中先执行微任务 打印3
然后执行异步的一个宏任务 打印1
然后执行异步的微任务 打印7
然后执行异步的一个宏任务 打印8
然后执行异步的微任务 打印4
然后执行最后一个宏任务 打印5