The whole process of axios sending a simple GET request was analyzed in the previous article, portal, stamp here.

This article will focus on how Axios implements interceptors, but only request interceptors.

axios.interceptors.request.use(function(config){
    // ...
    return config;
}, function(err){
    // ...
    return Promise.reject(err)
})
Copy the code

The above code defines a request interceptor. Note that the interceptor must be defined before the request is sent!

We already know that axios is a function, but when was the interceptors property defined? In the previous article, we looked at the axios/lib/core/ axios.js file, which has many attributes inherited from context and instance.

function Axios(){
    this.interceptors = {
        request = new InterceptorManager()
    }
}
Copy the code

Context is an Axios instantiation object. It has an Interceptors object, so it is also accessible from Axios. Know this is conveniently to axios/lib/core/InterceptorManager. See InterceptorManager js file the constructor!!!!

function InterceptorManager(){
    this.handlers = [];
}
InterceptorManager.prototype.use = function use(fulfilled, rejected){
    this.handlers.push({
        fulfilled : fulfilled,
        rejected : rejected
    });
    return this.handler.length - 1;
}
Copy the code

From the above you can see, the use is to define on the prototype of the constructor, so its instantiation object is accessible, so until now, axios. Interceptors. Request. Use () we have explained, is the above function, enter the function to see what did, Our completed and failed callbacks are pushed into a Handlers array, so what does this handlers array mean?

It seems that the analysis has been broken so far and I don’t know how to proceed, but we left out a few things about interceptors in the last section when we analyzed the axios.prototype. request method. Check out Axios /lib/core/ axios.js.

Axios.prototype.request = function(config){
    // ... 
    // The code that handles config is omitted
    var chain = [dispatchRequest, undefind];
    var promise = Promise.resolve(config);
    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor){
        // This is a function that was omitted from the previous analysis
        // The handlers array is iterated through;
        chain.unshift(interceptor.fulfilled, interceptor.rejected);
        // add the interceptor callback to the head of the chain
    })
    // Response is also omitted
    // Assuming we only defined a set of interceptor callbacks, the chain would now look like this
    // chain = [fulfilled, rejected, dispatchRequest, undefined];
    while(chain.length){
        promise = promise.then(chain.shift(), chain.shift())
    }
    // Over time this promise becomes a promise
    /** * promise = promise.resolve(conifg) * .then(interceptor.fulfilled, interceptor.rejected) * .then(dispatchRequest, undefined) */
    return promise
}
Copy the code

This function returns a promise after we send the request, but before sending the request, we perform the promise composed of Fufilled (config) and Rejected (err). This promise is executed and resolved before dispatchRequest(config) is executed; If a reject is returned, the request promise terminates and is caught by axios.get().catch(), so this is called an intercept.

This is a big pity for the response interceptor, but the interceptor. Rejected callback will be forgotten after the chain array. This will be a pity for the interceptor.

In summary, the process is pretty simple: the interceptor callback is executed before the promise that sends the request.

Analysis of cancellation requests, portal, poke here.