You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Node.js中Express API引发的Event Loop Blocking问题?

Node.js Event Loop阻塞问题的解决方法(Express API场景)

我用Express.js开发了两个API:第一个API包含从1循环至300万的for循环,执行时会打印大量日志;第二个API仅在控制台输出简单字符串。相关代码如下:

app.get('/firstAPI', (req, res) => {
    for (let i = 1; i <= 3000000; i++) {
        console.log('First API' + i);
    }
});

app.get('/secondAPI', (req, res) => {
    console.log('Here is the Second API');
});

调用第一个API时,长时间的同步执行会完全阻塞第二个API的调用,这确实是Node.js的Event Loop被阻塞导致的——Node.js是单线程模型,同步任务会一直占据主线程,让其他请求无法被处理。下面是几种可行的解决方法:


解决方法

1. 拆分长同步任务,主动让出Event Loop

把大的for循环拆分成多个小批次执行,每次处理一小部分后,用setImmediate把剩余任务放到下一个事件循环里,给主线程留出处理其他请求的时间。同时可以先给客户端返回响应,避免客户端长时间等待:

app.get('/firstAPI', (req, res) => {
  let current = 1;
  const batchSize = 1000; // 每次处理1000条
  const total = 3000000;

  function handleBatch() {
    const end = Math.min(current + batchSize, total);
    // 处理当前批次
    for (; current <= end; current++) {
      console.log(`First API ${current}`);
    }
    // 如果还有剩余任务,放到下一个事件循环
    if (current <= total) {
      setImmediate(handleBatch);
    }
  }

  handleBatch();
  res.send('First API 开始处理,请稍后查看日志');
});

2. 使用Worker Threads(工作线程)

Node.js的worker_threads模块可以把CPU密集型任务放到单独的线程中执行,完全不占用主线程,这样主线程可以正常处理其他API请求:

首先创建一个单独的工作线程文件firstAPIWorker.js:

const { parentPort } = require('worker_threads');

// 在工作线程中执行循环任务
for (let i = 1; i <= 3000000; i++) {
  parentPort.postMessage(`First API ${i}`);
}

parentPort.close();

然后在主文件中调用这个工作线程:

const { Worker } = require('worker_threads');
const path = require('path');

app.get('/firstAPI', (req, res) => {
  // 创建工作线程
  const worker = new Worker(path.join(__dirname, 'firstAPIWorker.js'));

  // 接收工作线程发送的日志信息
  worker.on('message', (logMsg) => {
    console.log(logMsg);
  });

  // 工作线程结束时通知客户端
  worker.on('exit', () => {
    res.send('First API 处理完成');
  });

  // 先给客户端返回响应
  res.send('First API 已在后台线程开始处理');
});

3. 优化日志输出

大量同步的console.log本身也会加重主线程阻塞,因为控制台输出是同步操作。可以:

  • 把日志内容缓存到数组中,批量输出,减少IO操作次数
  • 使用异步日志库(如winston、pino),这些库会把日志操作放到异步队列中,不阻塞主线程

内容的提问来源于stack exchange,提问作者Zhengzhe Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:42:44