there are two file, and command node main.js:
// main.js
(async () => {
const {
Worker
} = require('worker_threads')
const worker = new Worker(`${__dirname}/worker.js`)
for (let i = 0; i < 10; i++) {
await new Promise((resolve, reject) => {
// Section1: in this valid
// worker.removeAllListeners();
worker.on('message', (data) => {
// Section2: in this invalid
worker.removeAllListeners();
console.log(`data ${JSON.stringify(data)}`)
resolve(data)
})
worker.postMessage({
param: i
})
})
}
})()
// worker.js
const {
parentPort
} = require('worker_threads')
parentPort.on('message', async (data) => {
console.log(`worker on message: ${JSON.stringify(data)}`)
parentPort.postMessage(data)
})
when i run node main.js, you can see the result
worker on message: {"param":0}
data {"param":0}
worker on message: {"param":1}
data {"param":1}
worker on message: {"param":2}
data {"param":2}
worker on message: {"param":3}
data {"param":3}
worker on message: {"param":4}
data {"param":4}
worker on message: {"param":5}
data {"param":5}
worker on message: {"param":6}
data {"param":6}
worker on message: {"param":7}
data {"param":7}
worker on message: {"param":8}
data {"param":8}
worker on message: {"param":9}
data {"param":9}
worker on message: {"param":0}
data {"param":0}
worker on message: {"param":1}
when i use this line will be ok:
// in this valid
// worker.removeAllListeners();
I think this is happening because the Worker class manages its lifetime through 'newListener' and 'removeListener' listeners which check the presence of 'message' listeners. Using .removeAllListeners() removes those internal listeners as well.
That underlying problem isn’t specific to Workers – you’d run into the same problem with other parts of Node.js as well.
I’ll ping @nodejs/workers, but if nobody feels strongly about this (and has a good idea for how to do so), I’d close this as wontfix.
I agree with wontfix . My reason: The document for removeAllListerner is clear in terms of side effects: https://nodejs.org/dist/latest-v14.x/docs/api/events.html#events_emitter_removealllisteners_eventname - It is bad practice to remove listeners added elsewhere in the code...
I don't know why i use removeALlListener in Setion1, it will be ok and listener will be trigger again. What's the difference ?
@JianmingXia I think it depends on whether you remove the listeners while the Worker object is having .on('message') listeners or not.
Most helpful comment
I think this is happening because the
Workerclass manages its lifetime through'newListener'and'removeListener'listeners which check the presence of'message'listeners. Using.removeAllListeners()removes those internal listeners as well.That underlying problem isn’t specific to
Workers – you’d run into the same problem with other parts of Node.js as well.I’ll ping @nodejs/workers, but if nobody feels strongly about this (and has a good idea for how to do so), I’d close this as
wontfix.