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

關於取消請求的分析,傳送門,戳這裏

相關文章
相關標籤/搜索