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

Node.js Worker Thread Promise未完成线程已退出问题求助

Node.js Worker Threads 提前退出导致Promise.all未完成的解决方法

你的代码存在几个关键问题,导致Worker线程还没完成任务就提前退出,最终Promise.all无法等到结果:


1. Worker 消息监听方式错误

在worker_threads模块里,不能直接用onmessage = ...绑定消息事件——这是浏览器Web Worker的写法,Node.js的Worker Threads需要通过parentPort.on('message', 回调)来监听主线程发送的消息。原写法里onmessage根本不会触发,Worker启动后没有活跃的事件监听或异步任务,直接就退出了。

2. setTimeoutPromise实现错误

setTimeout本身不是Promise,你不需要await它,而且Promise的执行器函数不能用async——这会导致内部抛出的错误无法被Promise的reject捕获。另外,await setTimeout(...)完全无效,因为setTimeout返回的是定时器ID,不是Promise对象。

3. 主线程未处理Worker异常退出的情况

原代码里Worker退出时只打印日志,但如果Worker意外退出,对应的Promise不会被reject,会导致Promise.all一直挂起或者静默失败。


下面是修正后的完整代码:

main.js

const { Worker } = require("node:worker_threads");

(async () => {
  try {
    const results = await Promise.all(
      Array.from(Array(100), (_, i) => i).map((i) =>
        new Promise((resolve, reject) => {
          const worker = new Worker("./worker.js");
          worker.postMessage(i);

          // 接收Worker返回的结果
          worker.on("message", (event) => {
            resolve(event);
            worker.terminate(); // 任务完成后主动终止Worker,释放资源
          });

          // 捕获Worker执行错误
          worker.on("error", reject);

          // 处理Worker退出事件,非0退出码时标记Promise失败
          worker.on("exit", (code) => {
            console.log(`worker ${i} exited with code ${code}`);
            if (code !== 0) {
              reject(new Error(`Worker ${i} exited unexpectedly with code ${code}`));
            }
          });
        })
      )
    );
    console.log("所有任务完成:", results);
  } catch (err) {
    console.error("任务执行失败:", err);
  }
})();

worker.js

const { parentPort } = require("node:worker_threads");

// 正确封装setTimeout为Promise
const setTimeoutPromise = (ms) => {
  return new Promise(resolve => setTimeout(resolve, ms));
};

// 正确监听主线程发送的消息
parentPort.on("message", async (index) => {
  console.log(`receive index: ${index}`);
  await setTimeoutPromise(1500);
  parentPort.postMessage(`worker ${index} return`);
});

修正后,每个Worker会正确接收消息、执行延迟任务并返回结果,主线程的Promise.all会等待所有Worker完成后输出结果,Worker在任务结束后会被主动终止,不会出现提前退出的问题。

内容的提问来源于stack exchange,提问作者Carl.t_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:43:28