I am trying to make a test of offloading task to worker thread.
The workflow is quite simple, I have 100 promises of array, each promise will create a worker thread.
The main thread will pass the index to the worker thread, the worker thread will wait 1.5sec then return the index to main thread.
main.js:
const { Worker } = require("node:worker_threads");
(async () => {
await Promise.all(
Array.from(Array(100), (x, i) => i).map(
(i) =>
new Promise((resolve, reject) => {
const worker = new Worker("./worker.js");
worker.postMessage(i);
worker.on("message", (event) => resolve(event));
worker.on("error", reject);
worker.on("exit", (code) => console.log(`worker ${code} exited`));
})
)
)
.then((results) => console.log(results))
.catch((err) => console.log(err));
})();
worker.js
const { workerData, parentPort } = require("node:worker_threads");
const setTimeoutPromise = (ms) => {
return new Promise(async (resolve, reject) => {
await setTimeout(() => {
resolve();
}, ms);
});
};
onmessage = async (index) => {
console.log(`receive index: ${index}`);
await setTimeoutPromise(1500);
parentPort.postMessage(`worker ${index} return`);
};
But even the Promise.all haven't return result, all worker thread is exited and the application is done.
How can I wait all worker thread promises finish like simple promises does?
I think that this code just creates a variable called onmessage
instead of assigning the listener
onmessage = async (index) => {
console.log(`receive index: ${index}`);
await setTimeoutPromise(1500);
parentPort.postMessage(`worker ${index} return`);
};
Try using this instead:
parentPort.once('message', async (index) => {
console.log(`receive index: ${index}`);
await setTimeoutPromise(1500);
parentPort.postMessage(`worker ${index} return`);
});
You can also use on
instead of once
if you want to listen for more than one message
event