一.概念
JS有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。
定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫时间循环。
原因:JS是単线程,为了让耗时的代码不阻塞其他代码运行,设计了事件循环模型
二、事件循环-执行过程
注意:浏览器是多线程,JS才是单线程
详细例子说明(超详细)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件循环</title>
</head>
<body>
<script>
/**
* 目标:阅读并回答执行的顺序结果
*/
console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
console.log(3)
setTimeout(() => {
console.log(4)
}, 2000)
console.log(5)
</script>
</body>
</html>
第一行代码,是同步代码,放入调用栈里面立即执行,控制台打印:1,执行完以后立马出栈
第二行代码是一个异步代码,放入宿主环境,宿主环境发现是一个零秒的计时器,立马把这段代码推入到任务队列当中,所以控制台此时并没有打印2,因为它此时在任务队列当中排队。
第三段代码,是一个同步代码,放入调用栈里立即执行,控制台打印3,并出栈。
第四段代码是异步代码,放入宿主环境里面等待2秒,在这2秒当中JS引擎会继续往下执行代码,由于第五段代码是同步代码,所以放入调用栈里面立即执行,控制台打印5,然后立马出栈。
当调用栈是空闲的时候,它会一直反复的尝试到任务队列里面调用要执行的回调函数
推入调用栈以后,立马执行该代码,打印2,然后出栈。
当宿主环境里的2秒过去以后,立马推入任务队列
此时调用栈处于空闲状态,到任务队列里面调用要执行的回调函数,推入到调用栈以后,立马执行,控制台打印4,然后出栈
上面是我们手工结果,我们运行代码看看结果是不是这样
结果正确!
三、宏任务与微任务
1.介绍
ES6之后引入了Promise对象,让JS引擎也可以发起异步任务
异步任务分为:
宏任务:由浏览器环境执行的异步代码
微任务:由JS引擎环境执行的异步代码
2.宏任务与微任务的代码
宏任务:
微任务:
注意:Promise本身是同步的,而then和catch回调函数是异步的
3.详细例子说明(超详细)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微任务与宏任务</title>
</head>
<body>
<script>
/**
* 目标:阅读并回答打印的执行顺序
*/
console.log(1)
setTimeout(() => {
console.log(2)
}, 0)
const p = new Promise((resolve, reject) => {
console.log(3)
resolve(4)
})
p.then(result => {
console.log(result)
})
console.log(5)
</script>
</body>
</html>
第一段是同步代码,放入调用栈中直接打印1,然后出栈
第二段是异步代码,放入宿主环境中,因为是0秒倒计时,且是宏任务,所以放入宏任务队列当中
第三段代码是同步代码,放入调用栈中理解执行,控制台打印3,resolve(4)是标记Promise处于成功状态
第四段代码p.then是同步的放入调用栈中,里面的回调函数是异步代码,且是微任务,所以放入微任务队列中
第五段代码是同步代码,放入调用栈中立即执行,控制台打印5,然后出栈
此时所有的同步代码都已执行完成,调用栈空闲,会反复的尝试到任务队列里面调用要执行的回调函数,由于微任务更接近JS引擎,所以优先调用微任务队列里面的回调函数,然后在调用栈里理解执行,控制台打印4,然后出栈
由于微任务队列已经清空了,所以开始调用宏任务里的回调函数(必须先清空微任务队列里的回调函数),然后在调用栈里立即执行打印2,然后出栈
让我们看看执行的结果是不是这样
对啦!
四、总结
当然还有我们的模型图