JavaScript中的事件循环到底怎么回事

JavaScript是一门单线程的语言,因此,JavaScript在同一个时间只能做一件事,单线程意味着,如果在同个时间有多个任务的话,这些任务就需要进行排队,前一个任务执行完,才会执行下一个任务。

在JS引擎线程中, “多线程”和异步操作是通过事件循环(Event Loop)来实现的。

  • 事件循环由三部分组成:
  1. 调用栈:存放要执行的函数
  2. 消息队列:存放宏任务的函数
  3. 微任务队列:存放微任务的函数
    在这里插入图片描述

事件循环刚开始时(其实,就是当前宏任务中所有的同步任务,因为script整段代码就是宏任务),会从全局栈代码开始一行一行执行,遇到函数调用就把函数压入调用栈中,被压入的函数叫做(Frame),函数执行完毕后弹出调用栈。

JavaScript中的异步操作:

宏任务:AJAX、事件回调、setTimeout中的回调函数、setInterval中的回调函数,会入队到消息队列中,消息会在调用栈清空后,被压入到调用栈中执行

微任务:Promise.then的回调函数、async await等,入队到微任务队列中,在调用栈被清空后立即执行(在宏任务前执行),且执行过程中产生的新的微任务会在此次循环中一同执行。

关于一轮事件循环始末

一次事件循环:本次宏任务、本次宏任务产生的微任务、以及本次微任务产生的微任务全部执行结束,本次事件循环结束。本次事件循环产生的宏任务将在下一次事件循环中执行。
例如:

<script>
	setTimeout(function () {
	  console.log('three');
	}, 0);
	
	Promise.resolve().then(function () {
	  console.log('two');
	});
	
	console.log('one');
</script>

// 结果:
// one
// two
// three

一轮事件循环:

  1. 宏任务为本段script代码
  2. 遇到setTimeout,为宏任务,将setTimeout的回调函数放入消息队列,将在下一轮事件循环中执行
  3. 遇到Promise.then,为微任务,将then的回调函数放入微任务队列
  4. 遇到console.log(‘one’),压入调用栈,执行,输出one,弹出调用栈
  5. 此时调用栈为空,立即将微任务队列中的then回调函数压入调用栈,执行,输出two,弹出调用栈
  6. 调用栈为空
    --------------------------------------本轮事件循环结束-----------------------------------------------
  7. 新一次事件循环开始,将消息队列中setTimeout的回调函数压入调用栈中,执行,输出three,弹出调用栈
  8. 调用栈为空
    --------------------------------------本轮事件循环结束-----------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值