Skip to content
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
    });
    // 调用use方法之后,返回当前拦截器的索引,以支持手动注销
    return this.handlers.length - 1;
  }

  // 注销拦截器
  eject(id) {
    if (this.handlers[id]) {
      // 这里是将对应索引项,设置为null
      this.handlers[id] = null;
    }
  }

  // 清除当前实例的所有拦截器
  clear() {
    if (this.handlers) {
      this.handlers = [];
    }
  }

  // 遍历拦截器
  forEach(fn) {
    utils.forEach(this.handlers, function forEachHandler(h) {
      // 过滤null项,即已经被注销的拦截器
      if (h !== null) {
        fn(h);
      }
    });
  }
}

InterceptorManager 类的源码比较通俗易懂。

以请求拦截器为例,我们在使用的时候:

js
const fulfilled = (config) => {}
const rejected = (err) => {}
const options = {
  synchronous: false,
  runWhen: null
}

axios.interceptors.request.use(fulfilled, rejected, options)

然后就会被按照 interceptor 对象注册到 handlers 中:

js
const interceptor = {
  fulfilled,
  rejected,
  synchronous,
  runWhen
}

this.handlers.push(interceptor)