Skip to content

Commit

Permalink
Fix removing abort listener after promise rejects (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
x51xxx authored Jan 1, 2025
1 parent 3cabb7a commit fd93994
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
10 changes: 5 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export default function pTimeout(promise, options) {
} = options;

let timer;
let abortHandler;

const wrappedPromise = new Promise((resolve, reject) => {
if (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {
Expand All @@ -56,15 +57,11 @@ export default function pTimeout(promise, options) {
reject(getAbortedReason(signal));
}

const abortHandler = () => {
abortHandler = () => {
reject(getAbortedReason(signal));
};

signal.addEventListener('abort', abortHandler, {once: true});

promise.finally(() => {
signal.removeEventListener('abort', abortHandler);
});
}

if (milliseconds === Number.POSITIVE_INFINITY) {
Expand Down Expand Up @@ -111,6 +108,9 @@ export default function pTimeout(promise, options) {

const cancelablePromise = wrappedPromise.finally(() => {
cancelablePromise.clear();
if (abortHandler && options.signal) {
options.signal.removeEventListener('abort', abortHandler);
}
});

cancelablePromise.clear = () => {
Expand Down
27 changes: 27 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,31 @@ if (globalThis.AbortController !== undefined) {
addEventListenerSpy.restore();
removeEventListenerSpy.restore();
});

test('removes abort listener after promise rejects', async t => {
const abortController = new AbortController();
const {signal} = abortController;

const addEventListenerSpy = sinon.spy(signal, 'addEventListener');
const removeEventListenerSpy = sinon.spy(signal, 'removeEventListener');

const promise = pTimeout(
(async () => {
await delay(50);
throw new Error('Test error');
})(),
{
milliseconds: 100,
signal,
},
);

await t.throwsAsync(promise, {message: 'Test error'});

t.true(addEventListenerSpy.calledWith('abort'), 'addEventListener should be called with "abort"');
t.true(removeEventListenerSpy.calledWith('abort'), 'removeEventListener should be called with "abort"');

addEventListenerSpy.restore();
removeEventListenerSpy.restore();
});
}

0 comments on commit fd93994

Please sign in to comment.