JS事件循环与宏任务-微任务

其实关于JS的事件循环,自己之前是有部分了解的,但是这个了解还不够详细和深刻。今天看到一个有趣的JS题目,由此引发了自己对于这一块知识的深入学习和梳理。

题目如下:

	setTimeout(function(){
		console.log(1);
	},0)
	
	new Promise(function(resolve) {
	    console.log(2);
	    resolve();
	}).then(function() {
	    console.log(3)
	})
	
	console.log(4);

问具体的输出结果?正确的解答这道题,你必须明白JS中的两个概念 -事件循环和宏任务、微任务。
我们先来看js中的事件循环,这里盗用一张图

在这里插入图片描述

导图要表达的内容用文字来表述的话:

  • 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

广义的同步任务和异步任务,我们对任务有更精细的定义:

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

有了上面这些基础知识,下面进行上面代码的详细

  1. 这段代码作为宏任务,进入主线程。
  2. 先遇到setTimeout,那么将其回调函数注册后分发到宏任务Event Queue。(注册过程与上同,下文不再描述)
  3. 接下来遇到了Promise,new Promise立即执行,then函数分发到微任务Event Queue。
    遇到console.log(),立即执行。
  4. 好啦,整体代码script作为第一个宏任务执行结束,看看有哪些微任务?我们发现了then在微任务Event Queue里面,执行。
  5. ok,第一轮事件循环结束了,我们开始第二轮循环,当然要从宏任务Event Queue开始。我们发现了宏任务Event Queue中setTimeout对应的回调函数,立即执行。
  6. 结束

这里还有一个重要的知识点,那就是事件循环,宏任务,微任务的关系,如图所示:

在这里插入图片描述

下面是我自己的总结。
JS是单线程的,它是通过事件循环机制来实现异步的。

首先是主线程执行当前栈中的任务,遇到同步任务继续执行,遇到异步任务会将其放入Event Tables的事件队列中。Event Tables的事件队列又分为两类,一类是宏任务,一类是微任务。
当主线程的任务执行完毕后,回去任务队列中取出任务来执行。此时会优先选取任务队列中的微任务,执行完微任务后,才会去取宏任务执行。

对了,忘记说了,正确输出是2,4,3,1。你做对了吗?

本文参考自以下文章:

  1. 这一次,彻底弄懂 JavaScript 执行机制

  2. 并发模型与事件循环

  3. 理解 JavaScript 中的 macrotask 和 microtask

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值