node/test/parallel/test-worker-message-port.js
Anna Henningsen 77a944cdee worker: use fake MessageEvent for port.onmessage
Instead of passing the payload for Workers directly to `.onmessage`,
perform something more similar to what the browser API provides,
namely create an event object with a `.data` property.

This does not make `MessagePort` implement the `EventTarget` API, nor
does it implement the full `MessageEvent` API, but it would make
such extensions non-breaking changes if we desire them at
some point in the future.

(This would be a breaking change if Workers were not experimental.
Currently, this method is also undocumented and only exists with
the idea of enabling some degree of Web compatibility.)

PR-URL: https://github.com/nodejs/node/pull/26082
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
2019-02-28 23:35:31 +11:00

81 lines
2.0 KiB
JavaScript

'use strict';
const common = require('../common');
const assert = require('assert');
const { MessageChannel, MessagePort } = require('worker_threads');
{
const { port1, port2 } = new MessageChannel();
assert(port1 instanceof MessagePort);
assert(port2 instanceof MessagePort);
const input = { a: 1 };
port1.postMessage(input);
port2.on('message', common.mustCall((received) => {
assert.deepStrictEqual(received, input);
port2.close(common.mustCall());
}));
}
{
const { port1, port2 } = new MessageChannel();
port1.onmessage = common.mustCall((message) => {
assert.strictEqual(message.data, 4);
assert.strictEqual(message.target, port1);
port2.close(common.mustCall());
});
port1.postMessage(2);
port2.onmessage = common.mustCall((message) => {
port2.postMessage(message.data * 2);
});
}
{
const { port1, port2 } = new MessageChannel();
const input = { a: 1 };
port1.postMessage(input);
// Check that the message still gets delivered if `port2` has its
// `on('message')` handler attached at a later point in time.
setImmediate(() => {
port2.on('message', common.mustCall((received) => {
assert.deepStrictEqual(received, input);
port2.close(common.mustCall());
}));
});
}
{
const { port1, port2 } = new MessageChannel();
const input = { a: 1 };
const dummy = common.mustNotCall();
// Check that the message still gets delivered if `port2` has its
// `on('message')` handler attached at a later point in time, even if a
// listener was removed previously.
port2.addListener('message', dummy);
setImmediate(() => {
port2.removeListener('message', dummy);
port1.postMessage(input);
setImmediate(() => {
port2.on('message', common.mustCall((received) => {
assert.deepStrictEqual(received, input);
port2.close(common.mustCall());
}));
});
});
}
{
assert.deepStrictEqual(
Object.getOwnPropertyNames(MessagePort.prototype).sort(),
[
'close', 'constructor', 'onmessage', 'postMessage', 'ref', 'start',
'unref'
]);
}