axios源码分析——拦截器

上一篇中分析了axios发送一个简单的get请求的完整的流程,传送门,戳这里javascript

这一篇讲主要来分析下axios是如何实现拦截器的,这里只分析请求拦截器。java

axios.interceptors.request.use(function(config){
    // ...
    return config;
}, function(err){
    // ...
    return Promise.reject(err)
})
复制代码

上面的代码就是定义一个请求的拦截器,须要注意的是拦截器是要在发送请求以前定义的!ios

axios是一个函数咱们都知道了,interceptors属性是何时定义上的呢?上一篇分析了axios上好多属性都是从context和instance上继承来的,因此仍是按照整个思路分析,来看axios/lib/core/Axios.js文件。axios

function Axios(){
    this.interceptors = {
        request = new InterceptorManager()
    }
}
复制代码

context是Axios的实例化对象,有interceptors对象,因此axios继承来,也是能够访问的到的,清楚这一点就顺势去axios/lib/core/InterceptorManager.js文件中看InterceptorManager这个构造函数吧!数组

function InterceptorManager(){
    this.handlers = [];
}
InterceptorManager.prototype.use = function use(fulfilled, rejected){
    this.handlers.push({
        fulfilled : fulfilled,
        rejected : rejected
    });
    return this.handler.length - 1;
}
复制代码

从上面能够看到,use是定义在构造函数的原型上的,因此它的实例化对象是能够访问的,因此到如今,axios.interceptors.request.use()咱们已经解释清楚了,就是上面的函数,进入函数看下到底作了什么,咱们定义的完成和失败的两个回调函数被push到一个handlers数组中去了,那么这个handlers数组到底有什么意义呢?promise

目前来讲好像分析被中断了,不知道该如和进行下去,可是上一节咱们在分析Axios.prototype.request方法的时候省略过一些关于拦截器的东西,去看看axios/lib/core/Axios.js函数

Axios.prototype.request = function(config){
    // ... 
    // 对config进行处理的代码仍是省略掉
    var chain = [dispatchRequest, undefind];
    var promise = Promise.resolve(config);
    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor){
        // 这是上一节分析省略掉的一个函数 
        // 关于这个forEach函数就是去遍历 刚才不知道是什么用的handlers数组;
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
        // 就是把咱们定义的拦截器的回调函数加入到chain的首部
    })
    // 关于response的也省略掉
    // 假设咱们只定义了一组拦截器回调函数,那么如今chain应该是这样的
    // chain = [fulfilled, rejected, dispatchRequest, undefined];
    while(chain.length){
        promise = promise.then(chain.shift(), chain.shift())
    }
    // 通过循环这个promise就成了
    /** * promise = promise.resolve(conifg) * .then(interceptor.fulfilled, interceptor.rejected) * .then(dispatchRequest, undefined) */
    return promise
}
复制代码

结合上一篇咱们知道这个函数返回的promise是咱们发送请求以后的promise,可是在发送请求以前先执行了fufilled(config)和rejected(err)组成的promise,这个promise执行而且resolve后才会去执行dispatchRequest(config);若是返回了reject那么请求promise将终止,会被axios.get().catch()捕获,因此这就是所谓的拦截。post

对响应拦截器的处理也一样是这个道理,只是将interceptor.fulfilled和interceptor.rejected回调放在了chain数组的后面,再此就不作分析啦!ui

总结一下,这个其实流程挺简单的,就是把拦截器的回调,放到发送请求的promise以前,先执行。this

关于取消请求的分析,传送门,戳这里

相关文章
相关标签/搜索