说说对事件循环的理解

94 阅读2分钟

事件循环的基本概念:

  • JavaScript 是一门单线程语言,意味着同一时间只能执行一件任务。然而,这并不意味着 JavaScript 无法执行非阻塞操作。这得益于事件循环机制。
  • 在 JavaScript 中,任务可以分为同步任务 和 异步任务:
    同步任务:这些任务立即执行,通常会进入主执行栈中进行处理;
    异步任务:这些任务如 ajax 请求或 setTimeout 等,不会立即执行,而是放在事件队列中,待主线程空闲时再执行。

微任务和宏任务:

  • 异步任务可以分为微任务和宏任务,其中微任务的时机早于宏任务。
  • 微任务包括但不限于:
    • promise.then、
    • MutationObserver(已废弃;Proxy 对象替代)、
    • Node.js中的process.nextTick
    • process.nextTick(Node.js)
  • 宏任务包括:
    • script (可以理解为外层同步代码/全局执行上下文)
    • setTimeout/setInterval
    • UI rendering(UI渲染)/UI事件
    • postMessage、MessageChannel
    • setImmediate、I/O(Node.js)
  • 在一个宏任务执行完毕后,引擎会查看是否存在微任务队列,如果有,则会依次执行这些微任务,然后再执行下一个宏任务。

async 和 await 的理解:

  • async标记的函数总是返回一个 promise 。如果函数返回非 promise 值,这个值会被包装在一个 resolved 的 Promise。
  • await 可以暂停 async 函数的执行,等待 Promise 处理完成。若跟随非 Promise 值,它会被转换为一个立即执行 resolve 的 Promise。
  • await 命令后面的代码会被暂停执行,直到前面的 Promise 状态变为 fullfilled 或 rejected,从而实现异步到同步的转换。

执行流程分析:

  • JavaScript 代码执行时,会从上到下依次解析同步代码,将微任务和宏任务依次放入对应的队列中。
  • 在当前宏任务执行完毕后,引擎会检查并执行所有队列中的微任务。只有当微任务队列为空时,才会执行下一次宏任务。
  • async / await 的运用实质上是微任务的应用,它允许我们以更同步的方式编写异步代码。

通过以上优化,我们提供了一个更清晰、更细化的对事件循环的解释,同时也涵盖了与事件循环相关的高级概念和实例分析。