当前位置:首页 > JavaScript

js eventloop实现

2026-04-05 22:00:52JavaScript

JavaScript 事件循环的实现原理

JavaScript 的事件循环(Event Loop)是其异步编程的核心机制,通过单线程处理任务队列实现非阻塞执行。以下是其实现的关键组成部分和运行逻辑:

调用栈(Call Stack)

调用栈负责跟踪当前执行的函数。当函数被调用时,会被推入栈顶;执行完毕后从栈顶弹出。若栈中任务耗时过长(如同步循环),会导致页面“冻结”。

function foo() {
  console.log("foo");
}
function bar() {
  foo();
}
bar(); // 调用栈顺序: bar -> foo -> console.log

任务队列(Task Queues)

异步任务完成后,其回调函数被放入对应的队列中,主要分为两类:

  • 宏任务队列(Macrotask Queue):包含 setTimeoutsetInterval、I/O 操作、UI 渲染等。
  • 微任务队列(Microtask Queue):包含 Promise.thenMutationObserverqueueMicrotask

事件循环流程

  1. 执行当前调用栈中的同步代码,直到栈为空。
  2. 检查微任务队列,依次执行所有微任务,直到队列清空。
  3. 渲染页面(如有需要)。
  4. 从宏任务队列中取出一个任务执行,回到步骤1。
console.log("Start");

setTimeout(() => console.log("Timeout"), 0);

Promise.resolve().then(() => console.log("Promise"));

console.log("End");
// 输出顺序: Start -> End -> Promise -> Timeout

关键特性

  • 微任务优先级高于宏任务:每次调用栈清空后,会先处理所有微任务。
  • 避免阻塞:长时间运行的同步代码会延迟事件循环,需将耗时任务拆解为异步操作。
  • Web Workers:可通过多线程分担计算密集型任务,与主线程通过 postMessage 通信。

手动模拟事件循环

以下代码模拟简化版事件循环:

js eventloop实现

class EventLoop {
  constructor() {
    this.macrotaskQueue = [];
    this.microtaskQueue = [];
  }

  enqueueMacrotask(task) {
    this.macrotaskQueue.push(task);
  }

  enqueueMicrotask(task) {
    this.microtaskQueue.push(task);
  }

  run() {
    while (true) {
      // 执行所有微任务
      while (this.microtaskQueue.length > 0) {
        const task = this.microtaskQueue.shift();
        task();
      }

      // 执行一个宏任务
      if (this.macrotaskQueue.length > 0) {
        const task = this.macrotaskQueue.shift();
        task();
      }
    }
  }
}

实际应用注意事项

  • 避免微任务嵌套过深:递归添加微任务可能导致无限循环。
  • 宏任务拆分:长时间任务可使用 setTimeoutrequestIdleCallback 分片执行。
  • Node.js 差异:Node.js 中 process.nextTick 优先级高于微任务,且存在 setImmediate 等特有 API。

通过理解事件循环机制,可以更好地优化代码性能并避免常见的异步陷阱。

标签: jseventloop
分享给朋友:

相关文章

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div cl…

js 实现倒计时

js 实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是两种常见实现方式。 使用 setInterval 实…

js实现全选

js实现全选

实现全选功能的方法 在JavaScript中实现全选功能通常涉及监听全选复选框的点击事件,并根据其状态控制其他复选框的选中状态。以下是几种常见的实现方式: 基础DOM操作实现 通过获取所有目标复选框…

js实现复制功能

js实现复制功能

使用 document.execCommand 方法 这种方法适用于较旧的浏览器,但在现代浏览器中可能被逐步淘汰。通过创建一个临时的 textarea 元素,将文本内容放入其中,然后执行复制命令。…

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…