From 43530f476214b2dabe5adc29e08f9d2b6833660f Mon Sep 17 00:00:00 2001 From: michal-billtech <94702944+michal-billtech@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:14:22 +0200 Subject: [PATCH] Clear abort listener Fixes #278 --- spec/index.spec.ts | 28 ++++++++++++++++++++++++++++ src/index.ts | 22 ++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/spec/index.spec.ts b/spec/index.spec.ts index 8591f34..d3e93a3 100644 --- a/spec/index.spec.ts +++ b/spec/index.spec.ts @@ -382,6 +382,34 @@ describe('axiosRetry(axios, { retries, retryCondition })', () => { setTimeout(() => abortController.abort(), 50); const timeStart = new Date().getTime(); }); + + it('should cancel old requests', (done) => { + const client = axios.create(); + setupResponses(client, [ + () => nock('http://example.com').get('/test').delay(100).reply(429), + () => nock('http://example.com').get('/test').delay(100).reply(429), + () => nock('http://example.com').get('/test').delay(100).reply(429) + ]); + axiosRetry(client, { + retries: 2, + retryCondition: () => true, + retryDelay: () => 0 + }); + const abortController = new AbortController(); + client + .get('http://example.com/test', { signal: abortController.signal }) + .then( + () => done.fail(), + (error) => { + expect(error).toBeInstanceOf(CanceledError); + expect(new Date().getTime() - timeStart).toBeLessThan(300); + done(); + } + ) + .catch(done.fail); + setTimeout(() => abortController.abort(), 250); + const timeStart = new Date().getTime(); + }); }); }); diff --git a/src/index.ts b/src/index.ts index 35cec8e..7f7443f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -255,17 +255,19 @@ async function handleRetry( if (config.signal?.aborted) { return Promise.resolve(axiosInstance(config)); } - return new Promise((resolve, reject) => { - const timeout = setTimeout(() => resolve(axiosInstance(config)), delay); + return new Promise((resolve) => { + const abortListener = () => { + clearTimeout(timeout); + resolve(axiosInstance(config)); + }; + const timeout = setTimeout(() => { + resolve(axiosInstance(config)); + if (config.signal?.removeEventListener) { + config.signal.removeEventListener('abort', abortListener); + } + }, delay); if (config.signal?.addEventListener) { - config.signal.addEventListener( - 'abort', - () => { - clearTimeout(timeout); - resolve(axiosInstance(config)); - }, - { once: true } - ); + config.signal.addEventListener('abort', abortListener, { once: true }); } }); }