Skip to content

Commit 2f65b39

Browse files
authored
Refactors middleware chain building (#20)
Instead of building a new promise chain on each request, I changed the logic to keep the chain and only update it when necessary.
1 parent 32147be commit 2f65b39

File tree

1 file changed

+44
-28
lines changed

1 file changed

+44
-28
lines changed

src/service.js

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
* @property {Array} middlewares stack
33
* @property {AxiosInstance} http
44
* @property {Function} originalAdapter
5-
* @property {Number} _requestInterceptor
6-
* @property {Number} _responseInterceptor
75
*/
86
export default class HttpMiddlewareService {
7+
/**
8+
* @param {AxiosInstance} [axios]
9+
*/
910
constructor(axios) {
1011
this.middlewares = [];
1112

13+
this._updateChain();
1214
this.setHttp(axios);
1315
}
1416

@@ -39,7 +41,7 @@ export default class HttpMiddlewareService {
3941
}
4042

4143
/**
42-
* @param {HttpMiddleware} middleware
44+
* @param {Object|HttpMiddleware} [middleware]
4345
* @returns {boolean} true if the middleware is already registered.
4446
*/
4547
has(middleware) {
@@ -48,7 +50,7 @@ export default class HttpMiddlewareService {
4850

4951
/**
5052
* Adds a middleware or an array of middlewares to the stack.
51-
* @param {HttpMiddleware|Array} middlewares
53+
* @param {Object|HttpMiddleware|Array} [middlewares]
5254
* @returns {HttpMiddlewareService}
5355
*/
5456
register(middlewares) {
@@ -57,24 +59,30 @@ export default class HttpMiddlewareService {
5759

5860
// Test if middlewares are registered more than once.
5961
middlewares.forEach((middleware) => {
62+
if (!middleware) return;
6063
if (this.has(middleware)) {
6164
throw new Error('Middleware already registered');
6265
}
6366
this.middlewares.push(middleware);
67+
this._addMiddleware(middleware);
6468
});
6569
return this;
6670
}
6771

6872
/**
6973
* Removes a middleware from the registered stack.
70-
* @param {HttpMiddleware} middleware
74+
* @param {Object|HttpMiddleware} [middleware]
7175
* @returns {HttpMiddlewareService}
7276
*/
7377
unregister(middleware) {
74-
const index = this.middlewares.indexOf(middleware);
75-
if (index > -1) {
76-
this.middlewares.splice(index, 1);
78+
if (middleware) {
79+
const index = this.middlewares.indexOf(middleware);
80+
if (index > -1) {
81+
this.middlewares.splice(index, 1);
82+
}
83+
this._updateChain();
7784
}
85+
7886
return this;
7987
}
8088

@@ -84,6 +92,7 @@ export default class HttpMiddlewareService {
8492
*/
8593
reset() {
8694
this.middlewares.length = 0;
95+
this._updateChain();
8796
return this;
8897
}
8998

@@ -92,32 +101,39 @@ export default class HttpMiddlewareService {
92101
* @returns {Promise}
93102
*/
94103
adapter(config) {
95-
const chain = [conf => this._onSync(this.originalAdapter.call(this.http, conf)), undefined];
96-
let promise = Promise.resolve(config);
97-
98-
this.middlewares.forEach((middleware) => {
99-
chain.unshift(
100-
middleware.onRequest && (conf => middleware.onRequest(conf)),
101-
middleware.onRequestError && (error => middleware.onRequestError(error))
102-
);
103-
});
104+
return this.chain.reduce(
105+
(acc, [onResolve, onError]) => acc.then(onResolve, onError),
106+
Promise.resolve(config)
107+
);
108+
}
104109

105-
this.middlewares.forEach((middleware) => {
106-
chain.push(
107-
middleware.onResponse && (response => middleware.onResponse(response)),
108-
middleware.onResponseError && (error => middleware.onResponseError(error))
109-
);
110-
});
110+
/**
111+
*
112+
* @param {Object} middleware
113+
* @private
114+
*/
115+
_addMiddleware(middleware) {
116+
this.chain.unshift([
117+
middleware.onRequest && (conf => middleware.onRequest(conf)),
118+
middleware.onRequestError && (error => middleware.onRequestError(error)),
119+
]);
111120

112-
while (chain.length) {
113-
promise = promise.then(chain.shift(), chain.shift());
114-
}
121+
this.chain.push([
122+
middleware.onResponse && (response => middleware.onResponse(response)),
123+
middleware.onResponseError && (error => middleware.onResponseError(error)),
124+
]);
125+
}
115126

116-
return promise;
127+
/**
128+
* @private
129+
*/
130+
_updateChain() {
131+
this.chain = [[conf => this._onSync(this.originalAdapter.call(this.http, conf)), undefined]];
132+
this.middlewares.forEach(middleware => this._addMiddleware(middleware));
117133
}
118134

119135
/**
120-
* @param promise
136+
* @param {Promise} promise
121137
* @returns {Promise}
122138
* @private
123139
*/

0 commit comments

Comments
 (0)