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

Node.js多进程:如何实时获取子进程输出而非进程结束后统一输出

如何让Node.js子进程实时输出内容?

你当前使用的child_process.exec会缓存子进程的所有输出,直到进程完全结束后才一次性返回结果,这就是为什么要等所有子进程结束才能看到输出。要实现实时打印,需要改用child_process.spawn——它以流的方式处理子进程的stdout和stderr,可以在输出产生时立即捕获。

修改后的代码如下:

const { spawn } = require("child_process");
const NUM_WORKERS = 5;

for (let i = 0; i < NUM_WORKERS; ++i) {
  // 使用spawn创建子进程,拆分命令与参数
  const worker = spawn("node", ["-e", "console.log(process.env.MY_VAR);"], {
    env: {
      MY_VAR: String(i), // spawn要求环境变量值为字符串类型
      PATH: process.env.PATH // 继承父进程PATH,避免子进程找不到node命令
    }
  });

  // 实时监听stdout输出
  worker.stdout.on("data", (data) => {
    const output = data.toString().trim();
    if (output) {
      console.log(`[stdout#${i}] ${output}`);
    }
  });

  // 实时监听stderr输出
  worker.stderr.on("data", (data) => {
    const output = data.toString().trim();
    if (output) {
      console.log(`[stderr#${i}] ${output}`);
    }
  });

  // 监听子进程退出事件
  worker.on("close", (code) => {
    if (code !== 0) {
      console.log(`[worker#${i}] 退出,退出码: ${code}`);
    }
  });

  // 监听子进程启动失败事件
  worker.on("error", (err) => {
    console.log(`[worker#${i}] 启动失败:`, err);
  });
}

关键改动说明:

  • 替换为spawn:spawn是Node.js处理流式输出的标准API,不会缓存子进程输出,每有数据产生就触发data事件,实现实时打印。
  • 命令参数拆分:spawn要求将命令和参数分开传入(第一个参数为命令,第二个为参数数组),不能像exec那样传入整串命令。
  • 环境变量处理:spawn的env对象中值必须是字符串,因此将数字i转为String;同时继承父进程的PATH,避免子进程找不到系统命令。
  • 流式事件监听:分别给stdout和stderr绑定data事件,每次获取到数据就立即处理打印,注意将Buffer转为字符串并去除多余换行。

exec与spawn的适用场景:

  • exec:适合子进程输出内容少、需要一次性获取完整结果的场景(比如执行简单shell命令获取返回值)。
  • spawn:适合需要实时处理输出、输出内容大或持续产生输出的场景(比如启动服务、执行长时间运行的脚本)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:01:07