JavaScript的 event Loop 事件循环笔记

176 阅读3分钟

一般面试官会这么问,出道题,让你说出打印结果。然后会问分别说说浏览器的node的事件循环,区别是什么,什么是宏任务和微任务,为什么要有这两种任务...

  本质是浏览器或Node解决单线程运行时不会阻塞的一种机制

  Event Loop (同步与异步)执行过程: 

①任务进入执行栈,区分同步任务与异步任务,同步任务进入主线中,异步任务首先到event table进行回调函数注册

②当异步任务的触发条件满足,将回调函数从Event Table压入Event Queue中

③ 主线程里面的同步任务执行完毕了,系统就会去Event Queue中读取异步的回调函数。

④只要主线程空了,就会去Evnet Queue读取回调函数,这个过程被称为Event Loop。

常见的异步任务:

①DOM事件

②AJAX,AXIOS请求

③定时器setTimeout和setInterval

④ES6的promise

JavaScript的异步任务是存在优先级的,主要是除了广义上的将任务划分为同步任务和异步任务,也对异步任务进行的更加的精细的划分,异步任务分为微任务与宏任务。 优先级: 微任务>宏任务

①宏任务(macrotask):script, AJAX, history traversal  I/O 定时器

②微任务(microtack): Promise.then, process.nectTick, Mutationobserver, Object.observe

 微任务和宏任务都有各自的Event Queue ,就各自的队列

Event Loop最终的执行过程: 

①代码开始执行后, 创建一个全局调用栈,script作为宏任务执行

②执行过程中同步任务立即执行,异步任务根据异步任务类型分别注册到微任务队列和宏任务队列

③同步任务执行完毕,查看微任务队列

      • 若存在微任务,将微任务队列全部执行(包括执行微任务过程中产生的新微任务)
      • 若无微任务,查看宏任务队列,执行第一个宏任务,宏任务执行完毕,查看微任务队列,重复上述操作,直至宏任务队列为空。

细节问题

①Node环境下的事件循环

和浏览器有什么不同?

只是一些版本上的差别,如果是node10及其之前的版本,微任务会在事件循环的各个阶段之间执行,也就是一个阶段执行完毕,就会去执行宏任务队列中的任务

②Promise.nextTick, setTimeout, setImmediate的使用场景和区别

①Promise.nextTick

Promise.nextTick是一个独立于Event Loop的任务队列,

在每个Event Loop阶段完成后回去检查nextTick队列,如果里面会有任务,会让这部分的任务优先于微任务执行,是所有异步任务中最快执行的。

②setTimeout:

setTimeout()方法是定义一个回调,并且希望这个回调在我们所指定的时间间隔后第一时间去执行

③setImmediate:

setImmediate()方法从意义上将是立即执行的意思,但是实际上他却是在一个固定的阶段才会执行回调event Loop 事件循环