From de48c5d626e056d5e6056099c881b878103fc20e Mon Sep 17 00:00:00 2001 From: Dmitriy Mozgovoy Date: Mon, 9 May 2022 19:12:29 +0300 Subject: [PATCH] Fixed race condition on immediate requests cancellation (#4261) * Fixes #4260: fixed race condition on immediate requests cancellation * Update http.js Co-authored-by: Jay --- lib/cancel/CancelToken.js | 5 ++--- test/unit/adapters/http.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/cancel/CancelToken.js b/lib/cancel/CancelToken.js index ee7989f918..07ec10e3b2 100644 --- a/lib/cancel/CancelToken.js +++ b/lib/cancel/CancelToken.js @@ -25,10 +25,9 @@ function CancelToken(executor) { this.promise.then(function(cancel) { if (!token._listeners) return; - var i; - var l = token._listeners.length; + var i = token._listeners.length; - for (i = 0; i < l; i++) { + while (i-- > 0) { token._listeners[i](cancel); } token._listeners = null; diff --git a/test/unit/adapters/http.js b/test/unit/adapters/http.js index 3ba127a029..05adfea251 100644 --- a/test/unit/adapters/http.js +++ b/test/unit/adapters/http.js @@ -1166,6 +1166,34 @@ describe('supports http with nodejs', function () { }); }); + it('should able to cancel multiple requests with CancelToken', function(done){ + server = http.createServer(function (req, res) { + res.end('ok'); + }).listen(4444, function () { + var CancelToken = axios.CancelToken; + var source = CancelToken.source(); + var canceledStack = []; + + var requests = [1, 2, 3, 4, 5].map(function(id){ + return axios + .get('/foo/bar', { cancelToken: source.token }) + .catch(function (e) { + if (!axios.isCancel(e)) { + throw e; + } + + canceledStack.push(id); + }); + }); + + source.cancel("Aborted by user"); + + Promise.all(requests).then(function () { + assert.deepStrictEqual(canceledStack.sort(), [1, 2, 3, 4, 5]) + }).then(done, done); + }); + }); + it('should allow passing FormData', function (done) { var form = new FormData(); var file1= Buffer.from('foo', 'utf8');