卖坚果的怪叔叔 卖坚果的怪叔叔
  • 首页
  • 技术
  • 生活
  • 记录
  • 朋友
  • 常用代码
  • 关于
首页 › 技术 › 我不知道的Event Loop(事件循环)

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

坚果大叔
2019-12-27 17:40:47技术阅读数 271

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!!
下一篇
今日天气
摸鱼日历
摸鱼人日历
近期文章
  • 猫🐱
  • Input 空格问题
  • Sort函数小Tips😁😃❤️😒😭😩😳
  • 🌎🌎🌎🌎🌎🌎🌎🌎🌎🌎🌎🌎
  • element-ui中的Select选择器中remote-method方法带自定义参数
归档
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年5月
  • 2021年4月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年3月
  • 2018年2月
  • 2017年12月
  • 2017年11月
  • 2017年9月
Input 空格问题
2022-06-22 10:52:44
16 0 0
Sort函数小Tips😁😃❤️😒😭😩😳
2022-06-20 15:09:29
16 0 0
element-ui中的Select选择器中remote-method方法带自定义参数
2022-05-27 16:13:19
109 2 1
CSS之GAP属性
2022-05-25 19:28:05
90 2 2
  • 0
博主

一枚佛系前端开发,会一丢丢摄影,喜欢折腾,爱好美食。分享点前端技巧、笔记以及各种有趣的APP和资源教程♥♥

友链
Lieme
公众号
西豆 崔欣 执行上下文 卖坚果的怪叔叔 集赞助手
Copyright © 2017-2022 卖坚果的怪叔叔

苏ICP备18048410号-2
  • 首页
  • 技术
  • 生活
  • 记录
  • 朋友
  • 常用代码
  • 关于
# WordPress # # CSS #
坚果大叔
198
文章
47
评论
116
喜欢