JS-事件循环理解

wujiawen 发布于

事件循环解析(Event Loop)

  • 任务分为同步任务和异步任务

  • 同步任务会直接进入主线程执行

  • 异步任务则会进入任务队列(Event Queue)

  • 任务队列分为 宏任务(Macro Task)、微任务(Micro Task)

  • 在事件循环中,每进行一次循环操作称为tick,通过阅读规范可知,每一次 tick 的任务处理模型是比较复杂的,其关键的步骤可以总结如下:

  1. 在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次)
  2. 检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
  3. 更新 render
  4. 主线程重复执行上述步骤
  • (macro)task 主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)

  • microtask主要包含:Promise(这里指浏览器实现的原生 Promise)、MutaionObserver、process.nextTick(Node.js 环境)

  • 整体 script 作为第一个宏任务进入主线程

  • 简单总结:
    整体 script 作为第一个宏任务进入主线程,顺序执行 -> 遇到宏任务,则其回调函数被分发到宏任务 Event Queue 中 -> 遇到微任务,则其回调函数被分发到微任务 Event Queue 中 -> 此时,script宏任务执行完毕,开始执行微任务队列中的回调,直至清空微任务队列 -> 更新render -> 一次事件循环结束 -> 主线程重复事件循环执行

    疑惑

    何时注册宏任务或微任务?
    子线程执行异步接口需要一定的时间,是在异步接口执行之后才注册吗?
    还是遇到异步,就先注册回调?
    若有两个异步,一前一后,第一个执行时间比第二个要旧,不用await的情况下,哪个回调先执行?

    参考:
    https://www.cnblogs.com/yugege/p/9598265.html