interceptorManager
interceptorManager.js 是 Axios 中拦截器管理器的核心实现,位于 lib/core/InterceptorManager.js。
文件定义了一个 InterceptorManager 类,它采用职责链模式和观察者模式,用于管理请求和响应拦截器,提供了添加、移除和遍历拦截器的方法。
拦截器管理器本身不关心执行顺序,只负责存储和遍历。真正决定顺序逻辑在 /lib/core/Axios.js 的 request 方法中。
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import utils from '../utils.js';
class InterceptorManager { constructor() { this.handlers = []; }
use(fulfilled, rejected, options) { this.handlers.push({ fulfilled, rejected, synchronous: options ? options.synchronous : false, runWhen: options ? options.runWhen : null, }); return this.handlers.length - 1; }
eject(id) { if (this.handlers[id]) { this.handlers[id] = null; } }
clear() { if (this.handlers) { this.handlers = []; } }
forEach(fn) { utils.forEach(this.handlers, function forEachHandler(h) { if (h !== null) { fn(h); } }); } }
export default InterceptorManager;
|
this.handlers
InterceptorManager 类的核心属性是 handlers,它是一个数组,用于存储所有注册的拦截器。每个拦截器按注册顺序存储,执行时也是按此顺序,数组索引作为拦截器的 ID。
每个拦截器对象包含以下属性:
fulfilled:成功回调函数,用于处理成功响应。
rejected:失败回调函数,用于处理失败响应。
synchronous:是否同步执行,默认值为 false。
runWhen:运行条件,默认值为 null。
use(…) {}
源码:
1 2 3 4 5 6 7 8 9
| use(fulfilled, rejected, options) { this.handlers.push({ fulfilled, rejected, synchronous: options ? options.synchronous : false, runWhen: options ? options.runWhen : null, }); return this.handlers.length - 1; }
|
注册拦截器方法,将拦截器对象存入 handlers 数组并返回当前拦截器的索引(即 ID)。这个 ID 可用于后续通过 eject 方法移除该拦截器。
- fulfilled:Promise 成功时的处理函数(即 then 的回调)
- rejected:Promise 失败时的处理函数(即 catch 的回调)
- options:控制拦截器行为
- synchronous:是否同步执行(默认 false,异步执行)
- 条件判断函数,返回 false 时跳过该拦截器,可以基于请求配置动态决定是否使用某个拦截器
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const instance = axios.create();
instance.interceptors.request.use(function (config) { return config; }, function (error) { return Promise.reject(error); }, {
runWhen: function(config) { return config.method === 'get'; } });
instance.interceptors.response.use(function (response) { return response; }, function (error) { return Promise.reject(error); });
|
eject(id) {}
源码:
1 2 3 4 5
| eject(id) { if (this.handlers[id]) { this.handlers[id] = null; } }
|
移除拦截器方法,根据拦截器 ID 移除对应的拦截器。移除时,会将对应的拦截器移除后,将数组中的空位填充为 null,不是删除数组元素,而是设置为 null,可保持其他拦截器的 ID 不变(如果删除元素,后续 ID 会变化)。
使用示例:
1 2
| const myInterceptor = instance.interceptors.request.use(function () {}); instance.interceptors.request.eject(myInterceptor);
|
clear() {}
源码:
1 2 3 4 5
| clear() { if (this.handlers) { this.handlers = []; } }
|
重置 this.handlers 为空数组,用于重置实例的所有拦截器。
使用示例:
1
| instance.interceptors.request.clear();
|
forEach(fn) {}
源码:
1 2 3 4 5 6 7
| forEach(fn) { utils.forEach(this.handlers, function forEachHandler(h) { if (h !== null) { fn(h); } }); }
|
遍历 this.handlers 数组,对每个非 null 的拦截器调用 fn 函数(跳过被 eject 删除的拦截器)。