上一篇中分析了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
關於取消請求的分析,傳送門,戳這裏。