📜  javascript中的事件循环是什么(1)

📅  最后修改于: 2023-12-03 15:16:17.028000             🧑  作者: Mango

Javascript中的事件循环是什么

在Javascript中,存在一个事件循环(Event Loop)机制。这个机制控制着代码中异步操作(例如回调函数、Promise、setTimeout等)的执行顺序。了解事件循环机制,有助于开发者更好的理解Javascript的单线程执行模型,从而编写更高效、准确的代码。

事件循环流程

事件循环是一个不断循环的过程,每次循环被称为tick。以下是事件循环的基本流程:

  1. 执行同步任务,直到所有同步任务执行完毕。
  2. 执行当前tick中所有可以执行的异步任务,直到所有可执行异步任务被执行完毕。
  3. 若队列中存在macro-task(宏任务),则执行队列中所有的宏任务直到队列为空。否则,直接执行微任务。
  4. 将之前添加的所有已注册的微任务按照添加顺序依次执行(一个tick中,微任务仅仅只有全局唯一的一个队列,新的微任务会添加到该队列尾部,而不是创建新的队列)。
  5. 本轮事件循环结束,进入下一轮循环,重复上述过程。
微任务和宏任务

常见的异步操作分为两类:macro-task(宏任务)和micro-task(微任务)。

  • Macro-task,可作为一个独立的 task,在整个 task 执行前不需要等待其他异步操作完成。
    • 包括:setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering.
  • Micro-task,是一个相对较小的任务,需要等待 JavaScript 引擎清空执行栈中的所有任务后才执行。
    • 包括:process.nextTick, Promise, async/await中的await
代码示例
console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('Promise');
});

console.log('script end');

在上述代码中,会首先执行主机线任务(同步输出 script startscript end),接着执行微任务(Promise)的输出(输出 Promise)。最后,队列中没有宏任务,事件循环结束。但要注意,setTimeout中的回调函数虽然时间设为0,但它仍然属于宏任务,只是它被加入队列中可能会需要一些时间,而不是立即执行。因此,setTimeout最后输出 setTimeout

总结

Javascript的事件循环机制决定了异步代码的执行次序,它是Javascript中的重要概念,也是Javascript的单线程模型的基础。开发者必须深入了解事件循环机制的运作原理,以编写更加准确、高效的代码。