Skip to content

Instantly share code, notes, and snippets.

@shaseley
Created May 4, 2023 21:29
Show Gist options
  • Save shaseley/f16655b5a1e2ddcb2341d39d6ea5f2e8 to your computer and use it in GitHub Desktop.
Save shaseley/f16655b5a1e2ddcb2341d39d6ea5f2e8 to your computer and use it in GitHub Desktop.
AbortSignal.any() polyfill order POC
<script>
let abortProto = AbortController.prototype;
let oldAbort = AbortController.prototype.abort;
Object.assign(abortProto, {
abort(reason) {
oldAbort.call(this, reason);
if (this.signal.__dependents) {
for (let controller of this.signal.__dependents) {
controller.abort();
}
}
}
});
AbortSignal.any = function(signals) {
// ...after checking abort...
const controller = new AbortController();
const result = controller.signal;
result.__sources = [];
for (let signal of signals) {
if (signal.__sources) {
for (let source of signal.__sources) {
if (!source.__dependents) {
source.__dependents = [];
}
source.__dependents.push(controller);
result.__sources.push(source);
}
} else {
if (!signal.__dependents) {
signal.__dependents = [];
}
signal.__dependents.push(controller);
result.__sources.push(signal);
}
}
return result;
};
function run_test() {
const controller = new AbortController();
const signals = [];
// The first event should be dispatched on the originating signal.
signals.push(controller.signal);
// All dependents are linked to `controller.signal` (never to another
// composite signal), so this is the order events should fire.
signals.push(AbortSignal.any([controller.signal]));
signals.push(AbortSignal.any([controller.signal]));
signals.push(AbortSignal.any([signals[0]]));
signals.push(AbortSignal.any([signals[1]]));
let result = "";
for (let i = 0; i < signals.length; i++) {
signals[i].addEventListener('abort', () => {
result += i;
});
}
controller.abort();
// Should be "01234".
console.log(result);
}
run_test();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment