当问到,说一下事件循环(node、浏览器),我们该如何回答呐
回答套路步骤:
- 1,一句话简单总结,或说明重点
- 2,详细说明,这里附带需要的基础知识,举例说明
- 3,提出需要注意的地方,或者做下拓展
因此针对EventLoop应该如此回答。
- 1,一句话总结或重点
简单的说:EventLoop是一个过程,一个检查调用栈是否为空以及将某个任务放在调用栈的过程。它是JS异步的核心。
- 2,详细解答
详细的来说:我们都知道JS的任务分两种 同步 和 异步。
同步任务放在主线程中排队依次执行。
异步任务则放在任务队列,若有多个异步任务就需要在异步队列中排队等待。任务下一步是移到调用栈中。然后主线程执行调用栈。
- 3,举个栗子
比如说:ajax异步请求。ajax请求中,主线程在等待响应的过程中可以回去做其他事情。这是由于浏览器先在事件表中注册ajax的回调函数,响应回来后回调函数被添加到任务队列中等待执行,这个过程不会造成线程阻塞。因此说JS处理ajax请求是异步的。
- 4,提出需要注意的地方,或者做下拓展
在这里要注意浏览器的EventLoop和Node的EventLoop的区别。浏览器EventLoop的宏任务和微任务的执行流程。
可以问一下面试官,这里是否需要展开说一下。
小脑瓜里,想着浏览器EventLoop执行流程图片
- 1,浏览器先判断宏任务队列是否为空;
- 2,如果不为空,就取宏任务队列靠前的一个任务执行;
- 3,然后检查微任务队列,如果微任务队列不为空,则循环取出和执行微任务队列中的微任务,直到微任务队列为空
- 4,执行视图更新
- 5,这是浏览器EventLoop的流程,需要注意的是宏任务是执行一个后,执行产生的所有的微任务。常见的宏任务有SetTimeout、setInterval、IO输入等
微任务有Promise.then中的函数
(小脑瓜里,想着Node执行流程图片)
-
1,一句话总结,Node的和浏览器的EventLoop不同。Node采用V8作为JS的解析引擎,而IO使用的是libuv。libuv是一个基于事件驱动的跨平台抽象层,里面封装了不同操作系统一底层特性,对外提供统一的API。
-
2,Node的运行机制。
- V8引擎解析JS脚本。
- 解析后的代码,调用Node API。
- libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个事件循环,以异步的形式将任务的执行结果返回给V8引擎。
- V8引擎将结果返回给客户。
-
5,可以选择,拓展Node中的EventLoop
- 1,执行全局Script同步代码
- 2,执行微任务,先执行所有Next Tick Queue中的所有任务,再执行Other Microtask Queue中的所有任务
- 3,开始执行macrotask宏任务,共6个阶段,执行每个阶段的所有宏任务
- 4,每个阶段后执行微任务
注意:Node11新变化
node11在timer阶段的seetTimeout、setInterval。。。 和在check阶段的immediate,修改为一旦执行一个阶段的一个任务,立即执行微任务。为了和浏览器趋同。