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_
相关产品推荐
相关产品推荐

