卖坚果的怪叔叔 卖坚果的怪叔叔
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
首页 › 技术 › 我不知道的Event Loop(事件循环)

我不知道的Event Loop(事件循环)

坚果大叔
2019-12-27 17:40:47技术阅读 2,719

EventLoop是MS中的高频问题,理解繁琐,一步小心,步步入坑。

1、本文要点

1、EventLoop是什么?
2、任务队列是什么?
3、同步任务和异步任务?
4、微任务和宏任务?
...

2、EventLoop是什么?

我们都知道Js是单线程语言,即同一时间只能做一件事情,但是为了协调各种事件、用户交互、脚本加载、UI渲染和网络处理等行为,避免主线不阻塞,出现了EventLoop => ==事件循环==也就是我们常说的 异步 的方案。

过程:

在执行主线程的任务时,如果有异步任务,会进入到EventTable并注册回调函数,当指定的事情完成后,会将这个回调函数放到 ++callback queue++ 中

在主线程执行完毕之后,会去读取 callback queue中的回调函数,进入主线程执行

不断的重复这个过程,也就是常说的Event Loop(事件循环)了

3、任务队列是什么?

事件循环是通过任务队列的机制来进行协调的。一个EventLoop中,可以有一个或者多个任务队列(task queue),一个任务队列便是一系列有序任务(task)的集合;每个任务都有一个任务源(task source),源自同一个任务源的 task 必须放到同一个任务队列,从不同源来的则被添加到不同队列。

在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下:

1、在此次 tick 中选择最先进入队列的任务(oldest task),如果有则执行(一次)
2、检查是否存在 Microtasks,如果存在则不停地执行,直至清空 Microtasks Queue
3、更新 render
4、主线程重复执行上述步骤

4、同步任务和异步任务?

同步:一定要等任务执行完了,得到结果,才执行下一个任务。同步会阻塞代码运行,例如 alert
异步:异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中等待主线程空闲的时候(调用栈被清空),被读取到栈内等待主线程的执行。。例如 setTimeout

异步并不是同步,异步是单线程,异步指的是让CPU暂时搁置当前请求的响应,处理下一个请求,当通过轮询或其他方式得到回调通知后,开始运行。

通俗的讲

同步就是我强依赖你(对方),我必须等到你的回复,才能做出下一步响应。即我的操作(行程)是顺序执行的,中间少了哪一步都不可以,或者说中间哪一步出错都不可以,类似于编程中程序被解释器顺序执行一样;同时如果我没有收到你的回复,我就一直处于等待、也就是阻塞的状态。 异步则相反,我并不强依赖你,我对你响应的时间也不敏感,无论你返回还是不返回,我都能继续运行;你响应并返回了,我就继续做之前的事情,你没有响应,我就做其他的事情。也就是说我不存在等待对方的概念,我就是非阻塞的。

所以像setTimeOut定时任务、ajax请求都是需要一定的时间的,所以一般都是用异步方式,不会阻塞后边代码的执行,而是设置了定时时间之后、或发送了请求之后,就移动到单线程的任务队列的最尾端,等后边执行完之后再执行定时代码或者ajax请求的回调函数内代码。

注意:

异步并不是Js同时执行两段操作,它只是设定了定时的时间,然后放到任务队列的最后面,然后去执行其他操作,当设定的时间到了之后在把事件拿回来继续执行。

5、微任务和宏任务?

异步任务又分为 宏任务(MacroTask) 跟 微任务(MicroTask),主要区别在于执行顺序的不同。我们都知道js应该是按照语句先后顺序执行,在出现异步时,则发起异步请求,再接着往下执行,待异步结果返回后再接着执行。

注意:

这两个任务分别维护一个队列,均采用先进先出的策略进行执行!同步执行的任务都在宏任务上执行。

宏任务队列macrotask一次只从队列中取一个任务执行,执行完后就去执行微任务队列中的任务;
微任务队列中所有的任务都会被依次取出来执行,知道microtask queue为空;
5.1 宏任务(MacroTask)
  • script全部代码、
  • setTimeout、
  • setInterval、
  • setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、
  • I/O、
  • UI Rendering。
5.2 微任务(MicroTask)
  • Promise、
  • MutationObserver、
  • process.nextTick(Node.js 环境)。
5.3 执行顺序

我不知道的Event Loop(事件循环)-卖坚果的怪叔叔

1.首先执行同步代码,这属于宏任务

2.当执行完所有同步代码后,执行栈为空,查询是否有异步代码需要执行

3.执行所有微任务

4.当执行完所有微任务后,如有必要会渲染页面

5.然后开始下一轮EventLoop,执行宏任务中的异步代码,也就是setTimeout中的回调函数

6、结语

之前兜兜转转,总是忘记事件的执行顺序。长时间不接触,有些记忆越发的淡忘。只能不断重拾记忆,加深。

参考资料

  • js同步和异步
  • 前端中的事件循环eventloop机制
  • 带你彻底弄懂Event Loop
  • 用大白话告诉你什么是Event Loop
  • 一次弄懂Event Loop(彻底解决此类面试问题)
  • 从一道题浅说 JavaScript 的事件循环
赞赏 赞(0)
本文系作者 @坚果大叔 原创发布在 卖坚果的怪叔叔。未经许可,禁止转载。
前端每日两三问
上一篇
亦如沙粒,亦如星辰,我平凡的2019!!
下一篇
在小程序中查看

这是个😊,挣点服务器费用😜

热门文章
前端面试题整理
Python基础教程之条件判断和循环
重学Javascript之基础数据
Element render函数中使用map插入多条数据!
移动端常见布局方式
什么是函数?
专题标签
agent (1) CSS (15) dom (1) Es6入门系列 (14) Git (3) html (1) iview (1) JavaScript (9) js (4) Lif (1) Node (4) pyecharts (1) Python (10) ref (1) scriptable (1) Skill (1) vsCode (1) vue (4) wordpress (2) 三月 (1) 上海 (1) 假期 (1) 其他分享 (3) 前端两三问 (15) 古镇 (1) 外滩 (1) 对象 (1) 小程序 (5) 年度总结 (6) 年终总结 (1) 微信机器人 (4) 打字机 (1) 技术 (1) 日常问题 (8) 日常问题记录 (1) 春天 (2) 服务器 (2) 海族馆 (1) 生活 (8) 网上国网 (1) 记录 (3) 通勤 (1) 重学JavaScript (11) 面试题 (10) 🌸 (1)
什么是Agent?
2026-08-15 23:49:12
431 0 2
什么是 Skill?
2026-08-12 21:32:42
348 1 0
失业在家,我给小朋友做了一个练字小程序!
2026-08-07 16:21:52
690 10 1
上线8年,15万用户的小程序,一共赚了多少钱?
2026-05-30 18:01:24
4,683 4 0
  • 0
博主

一位佛系的前端开发者,略通摄影,乐于尝试新事物,热衷于美食。

友链
故事胶片
公众号
坚果大叔 执行上下文 卖坚果的怪叔叔 Dacking
Copyright © 2017-2026 卖坚果的怪叔叔

开往-友链接力

萌ICP备20230818号

苏ICP备18048410号-3
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
# CSS # # JavaScript # # vue # # 微信 # # 生活 #
坚果大叔
345
文章
171
评论
432
喜欢