diff --git a/lib/internal/worker.js b/lib/internal/worker.js index b6a7bbad671ecb..3cd5472b9341bd 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -224,8 +224,6 @@ class Worker extends EventEmitter { } terminate(callback) { - if (this[kHandle] === null) return; - debug(`[${threadId}] terminates Worker with ID ${this.threadId}`); if (typeof callback === 'function') { @@ -233,9 +231,12 @@ class Worker extends EventEmitter { 'Passing a callback to worker.terminate() is deprecated. ' + 'It returns a Promise instead.', 'DeprecationWarning', 'DEP0132'); + if (this[kHandle] === null) return Promise.resolve(); this.once('exit', (exitCode) => callback(null, exitCode)); } + if (this[kHandle] === null) return Promise.resolve(); + this[kHandle].stopThread(); // Do not use events.once() here, because the 'exit' event will always be diff --git a/test/parallel/test-worker-terminate-null-handler.js b/test/parallel/test-worker-terminate-null-handler.js new file mode 100644 index 00000000000000..3807501de025f0 --- /dev/null +++ b/test/parallel/test-worker-terminate-null-handler.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Worker } = require('worker_threads'); + +// Test that calling worker.terminate() if kHandler is null should return an +// empty promise that resolves to undefined, even when a callback is passed + +const worker = new Worker(` +const { parentPort } = require('worker_threads'); +parentPort.postMessage({ hello: 'world' }); +`, { eval: true }); + +process.once('beforeExit', common.mustCall(() => { + console.log('beforeExit'); + worker.ref(); +})); + +worker.on('exit', common.mustCall(() => { + console.log('exit'); + worker.terminate().then((res) => assert.strictEqual(res, undefined)); + worker.terminate(() => null).then( + (res) => assert.strictEqual(res, undefined) + ); +})); + +worker.unref();