mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const common = require('../common');
|
||
|
const { ok, strictEqual } = require('assert');
|
||
|
const { setImmediate: pause } = require('timers/promises');
|
||
|
|
||
|
function deferred() {
|
||
|
let res;
|
||
|
const promise = new Promise((resolve) => res = resolve);
|
||
|
return { res, promise };
|
||
|
}
|
||
|
|
||
|
(async () => {
|
||
|
const ac = new AbortController();
|
||
|
const mc = new MessageChannel();
|
||
|
|
||
|
const deferred1 = deferred();
|
||
|
const deferred2 = deferred();
|
||
|
const resolvers = [deferred1, deferred2];
|
||
|
|
||
|
mc.port1.onmessage = common.mustCall(({ data }) => {
|
||
|
data.addEventListener('abort', common.mustCall(() => {
|
||
|
strictEqual(data.reason, 'boom');
|
||
|
}));
|
||
|
resolvers.shift().res();
|
||
|
}, 2);
|
||
|
|
||
|
mc.port2.postMessage(ac.signal, [ac.signal]);
|
||
|
|
||
|
// Can be cloned/transferd multiple times and they all still work
|
||
|
mc.port2.postMessage(ac.signal, [ac.signal]);
|
||
|
|
||
|
mc.port2.close();
|
||
|
|
||
|
// Although we're using transfer semantics, the local AbortSignal
|
||
|
// is still usable locally.
|
||
|
ac.signal.addEventListener('abort', common.mustCall(() => {
|
||
|
strictEqual(ac.signal.reason, 'boom');
|
||
|
}));
|
||
|
|
||
|
await Promise.all([ deferred1.promise, deferred2.promise ]);
|
||
|
|
||
|
ac.abort('boom');
|
||
|
|
||
|
// Because the postMessage used by the underlying AbortSignal
|
||
|
// takes at least one turn of the event loop to be processed,
|
||
|
// and because it is unref'd, it won't, by itself, keep the
|
||
|
// event loop open long enough for the test to complete, so
|
||
|
// we schedule two back to back turns of the event to ensure
|
||
|
// the loop runs long enough for the test to complete.
|
||
|
await pause();
|
||
|
await pause();
|
||
|
|
||
|
})().then(common.mustCall());
|
||
|
|
||
|
{
|
||
|
const signal = AbortSignal.abort('boom');
|
||
|
ok(signal.aborted);
|
||
|
strictEqual(signal.reason, 'boom');
|
||
|
const mc = new MessageChannel();
|
||
|
mc.port1.onmessage = common.mustCall(({ data }) => {
|
||
|
ok(data instanceof AbortSignal);
|
||
|
ok(data.aborted);
|
||
|
strictEqual(data.reason, 'boom');
|
||
|
mc.port1.close();
|
||
|
});
|
||
|
mc.port2.postMessage(signal, [signal]);
|
||
|
}
|
||
|
|
||
|
{
|
||
|
// The cloned AbortSignal does not keep the event loop open
|
||
|
// waiting for the abort to be triggered.
|
||
|
const ac = new AbortController();
|
||
|
const mc = new MessageChannel();
|
||
|
mc.port1.onmessage = common.mustCall();
|
||
|
mc.port2.postMessage(ac.signal, [ac.signal]);
|
||
|
mc.port2.close();
|
||
|
}
|