javascript中的事件循环

javascript 中的事件循环,阐明了代码的执行顺序。其中涉及了调用栈(call stack)消息队列(message queue)宏任务(macrotask/task)微任务(microtask/job)这几个概念。

一. 可视化表示

下面这个图,是来自 MDN 的事件循环的可视化表示
事件循环的可视化表示

  1. 图中的 Stack 就是事件循环中的调用栈,它其中存放着一个一个的函数调用帧。每个函数调用后,就会创建一个调用帧放入栈中。每个帧都包含着对应函数的参数和局部变量。
  2. 图中的 Queue 是事件循环中的消息队列,它里面存放着一个一个的消息。这的消息,可以简单理解为一个个待执行的回调函数的引用。
  3. 当调用栈中的所有调用帧都执行完了,栈空的时候,事件循环就会从消息队列的队头里拿出一个消息,放入调用栈,执行它。
  4. 图中只划分出了一个简单的消息队列,其实还能细分为宏任务队列(task queue)和微任务队列(job queue)。

二. 伪代码表示

用一段伪代码表示 javascript 中的事件循环的话,应该是像下面这样的:

// 在循环中,不断轮询看调用栈中是否存在未执行的函数调用帧
while(true){
	// 如果存在未执行的函数调用帧,则执行它
	if(callStack.hasFrame()){
		excute(frame);
	} else {
		// 如果不存在未执行的函数调用帧,则去消息队列拿出队头的消息,进入调用栈后执行它
		let message = MessageQueue.getFirstMessage();
		excute(message);
	}
}

三. 事件循环过程阐述

  1. 事件循环检查调用栈里是否存在未执行的调用帧?如果有,执行它;执行完成后,将该调用帧出栈。
  2. 循环步骤1,直到调用栈为空。
  3. 检查微任务队列里是否存在排队中的微任务?如果有,则取出队列头的一个微任务,进入调用栈执行;执行完后,出栈。
  4. 循环步骤3,直到微任务队列为空。
  5. 检查宏任务队列里是否存在排队中的宏任务?如果有,则取出队列头的一个宏任务,进入调用栈执行;执行完后,出栈。
  6. 跳到步骤3,往下执行。

一句话概括一下,就是:调用栈里的调用帧执行完后,把微任务队列里的所有微任务执行完后,再执行一个宏任务;接下来依旧是执行依次所有微任务 --> 执行一个宏任务这样的过程。

四. 举例类比理解

  1. 调用栈和消息队列 vs 手头的工作和待接的 api 接口:

前端在写着前端代码,写着写着,发现缺少一个 api。
这时候,前端去告诉后端提供一个 api。然后,前端继续写自己的代码去了。
不过,前端每过一段时间,就会去询问后端是否准备好 api 接口了。
直到后端回答说准备好了,前端才会停止询问。
这时候,前端把 api 拿过来放在代办事项中;等手头的代码写完以后,再去处理代办事项里的东西。
如果代办事项里只有这一个事项,那就立即接入这个 api 接口。

  1. 宏任务队列和微任务队列 vs 普通队列和 VIP 队列:

某天,小胖去玩跳跳床。

假设:
每次只能有一个人玩跳跳床;
现在有一个人在玩着;
此时有 10 个人在排着队等着玩。
这时候:
你要玩的话,就只能乖乖排队;
一开始在玩的人出来以后,队列头的 1 人进入玩耍;
等前面的 10 个人都玩了以后,才能轮到你进入玩耍。

假设:
每次只能有一个人在玩跳跳床;
现在有一个人在玩着;
此时有 10 个人排在普通队列;
有 1 个人排在 VIP 队列;
你是 VIP。
这时候:
你要玩的话,就到 VIP 队列排队;
当一开始在玩的人出来以后,VIP 队列头的 1 人进入玩耍;
等这个人玩耍结束以后,就轮到你进入玩耍了!
后续:
你结束玩耍出来以后,

  1. 如果 VIP 队列依旧有人,则还是 VIP 队列头的 1 人进入玩耍;
  2. 如果 VIP 队列没人了,则普通队列头的 1 人可以进入玩耍。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值