我不知道的Event Loop
我不知道的Event Loop
LiemeEventLoop是MS中的高频问题,理解繁琐,一步小心,步步入坑。
1、本文要点
1 | 1、EventLoop是什么? |
2、EventLoop是什么?
我们都知道Js是单线程语言,即同一时间只能做一件事情,但是为了协调各种事件、用户交互、脚本加载、UI渲染和网络处理等行为,避免主线不阻塞,出现了EventLoop => ==事件循环==也就是我们常说的 异步 的方案。
过程:
1 | 在执行主线程的任务时,如果有异步任务,会进入到Event Table并注册回调函数,当指定的事情完成后, |
3、任务队列是什么?
事件循环是通过任务队列的机制来进行协调的。一个EventLoop中,可以有一个或者多个任务队列(task queue),一个任务队列便是一系列有序任务(task)的集合;每个任务都有一个任务源(task source),源自同一个任务源的 task 必须放到同一个任务队列,从不同源来的则被添加到不同队列。
1 | 在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下: |
4、同步任务和异步任务?
1 | 同步:一定要等任务执行完了,得到结果,才执行下一个任务。同步会阻塞代码运行,例如 alert |
异步并不是同步,异步是单线程,异步指的是让CPU暂时搁置当前请求的响应,处理下一个请求,当通过轮询或其他方式得到回调通知后,开始运行。
通俗的讲
同步就是我强依赖你(对方),我必须等到你的回复,才能做出下一步响应。即我的操作(行程)是顺序执行的,中间少了哪一步都不可以,或者说中间哪一步出错都不可以,类似于编程中程序被解释器顺序执行一样;同时如果我没有收到你的回复,我就一直处于等待、也就是阻塞的状态。 异步则相反,我并不强依赖你,我对你响应的时间也不敏感,无论你返回还是不返回,我都能继续运行;你响应并返回了,我就继续做之前的事情,你没有响应,我就做其他的事情。也就是说我不存在等待对方的概念,我就是非阻塞的。
所以像setTimeOut定时任务、ajax请求都是需要一定的时间的,所以一般都是用异步方式,不会阻塞后边代码的执行,而是设置了定时时间之后、或发送了请求之后,就移动到单线程的任务队列的最尾端,等后边执行完之后再执行定时代码或者ajax请求的回调函数内代码。
注意:
异步并不是Js同时执行两段操作,它只是设定了定时的时间,然后放到任务队列的最后面,然后去执行其他操作,当设定的时间到了之后在把事件拿回来继续执行。
5、微任务和宏任务?
异步任务又分为 宏任务(MacroTask) 跟 微任务(MicroTask),主要区别在于执行顺序的不同。我们都知道js应该是按照语句先后顺序执行,在出现异步时,则发起异步请求,再接着往下执行,待异步结果返回后再接着执行。
1 | 注意: |
5.1 宏任务(MacroTask)
- script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering。
5.2 微任务(MicroTask)
- Promise、 MutationObserver、 process.nextTick(Node.js 环境)。
5.3 执行顺序
1 | 1.首先执行同步代码,这属于宏任务 |
6、结语
之前兜兜转转,总是忘记事件的执行顺序。长时间不接触,有些记忆越发的淡忘。只能不断重拾记忆,加深。