From befe70ea00a930634866afeb9c2bcd6884114098 Mon Sep 17 00:00:00 2001 From: Christoph Reiter <reiter.christoph@gmail.com> Date: Tue, 11 Feb 2020 11:28:57 +0100 Subject: [PATCH] Add AbortController related helpers These allow linking multiple AbortControllers and ceate a timeout abort signal. For example in case you want to abort a fetch in case (1) the UI element gets removed (2) a newer request replacing this one gets started (3) a timeout happens because the fetch takes too long createLinkedAbortController() allows merging multiple signals into one and createTimeoutAbortSignal() allows creating a singal that auto aborts after some time passes. --- packages/common/index.js | 5 ++-- packages/common/src/abort.js | 37 +++++++++++++++++++++++++++ packages/common/{ => src}/eventbus.js | 0 packages/common/test/abort.js | 20 +++++++++++++++ packages/common/test/eventbus.js | 2 +- 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 packages/common/src/abort.js rename packages/common/{ => src}/eventbus.js (100%) create mode 100644 packages/common/test/abort.js diff --git a/packages/common/index.js b/packages/common/index.js index cb63e2ac..a562cd77 100644 --- a/packages/common/index.js +++ b/packages/common/index.js @@ -1,3 +1,4 @@ -import {EventBus} from './eventbus.js'; +import {EventBus} from './src/eventbus.js'; +import {createLinkedAbortController, createTimeoutAbortSignal} from './src/abort.js'; -export {EventBus}; \ No newline at end of file +export {EventBus, createLinkedAbortController, createTimeoutAbortSignal}; \ No newline at end of file diff --git a/packages/common/src/abort.js b/packages/common/src/abort.js new file mode 100644 index 00000000..33d59928 --- /dev/null +++ b/packages/common/src/abort.js @@ -0,0 +1,37 @@ +/** + * Takes multiple AbortSignal instances and returns a new AbortController which + * gets aborted if any of the AbortSignals do. + * + * @param {...AbortSignal} signals + * @returns {AbortController} + */ +export function createLinkedAbortController(...signals) { + const controller = new AbortController(); + + for (const signal of signals) { + if (signal.aborted) { + controller.abort(); + break; + } else { + signal.addEventListener('abort', () => { + controller.abort(); + }); + } + } + + return controller; +} + +/** + * Returns an AbortSignal which aborts after the specified time. + * + * @param {number} delay Delay in milliseconds + * @returns {AbortSignal} + */ +export function createTimeoutAbortSignal(delay) { + const controller = new AbortController(); + + setTimeout(() => {controller.abort(); }, delay); + + return controller.signal; +} \ No newline at end of file diff --git a/packages/common/eventbus.js b/packages/common/src/eventbus.js similarity index 100% rename from packages/common/eventbus.js rename to packages/common/src/eventbus.js diff --git a/packages/common/test/abort.js b/packages/common/test/abort.js new file mode 100644 index 00000000..9c0af4dc --- /dev/null +++ b/packages/common/test/abort.js @@ -0,0 +1,20 @@ +import {assert} from 'chai'; +import {createLinkedAbortController, createTimeoutAbortSignal} from '../src/abort.js'; + +suite('abort', () => { + test('createLinkedAbortController', () => { + let c1 = new AbortController(); + let c2 = new AbortController(); + const linked = createLinkedAbortController(c1.signal, c2.signal); + assert.isFalse(linked.signal.aborted); + c1.abort(); + assert.isTrue(linked.signal.aborted); + c1.abort(); + linked.abort(); + }); + + test('createTimeoutAbortSignal', () => { + const signal = createTimeoutAbortSignal(10000000); + assert.isFalse(signal.aborted); + }); +}); \ No newline at end of file diff --git a/packages/common/test/eventbus.js b/packages/common/test/eventbus.js index cf6d9403..209ff165 100644 --- a/packages/common/test/eventbus.js +++ b/packages/common/test/eventbus.js @@ -1,5 +1,5 @@ import {assert} from 'chai'; -import {EventBus, createEventName, checkIndentifier} from '../eventbus.js'; +import {EventBus, createEventName, checkIndentifier} from '../src/eventbus.js'; suite('helpers', () => { test('createEventName', () => { -- GitLab