如今來看axios的核心,構造函數Axios,它自己就是一個構造函數,而後在其原型prototype上綁定了一些方法,攔截器就在this.interceptors上ios
function Axios(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { request: new InterceptorManager(), // InterceptorManager也是一個構造函數 response: new InterceptorManager() }; }
原型prototype添加了request方法(用來發送請求),getUri方法(用來創建請求的路徑),還有就是一些方法的別名,好比axios.get()這種寫法,就是在prototype上添加了get方法,因此實例上能夠訪問的到axios
源碼分析以下數組
'use strict'; var utils = require('./../utils'); var buildURL = require('../helpers/buildURL'); var InterceptorManager = require('./InterceptorManager'); var dispatchRequest = require('./dispatchRequest'); var mergeConfig = require('./mergeConfig'); /** * 構造函數Axios * * @param {Object} instanceConfig 默認配置 */ function Axios(instanceConfig) { this.defaults = instanceConfig; this.interceptors = { request: new InterceptorManager(), // InterceptorManager也是一個構造函數 response: new InterceptorManager() }; } /** * 分發一個請求 * * @param {Object} config 請求的配置 (跟默認配置合併) */ Axios.prototype.request = function request(config) { // config就是axios({})中的{} /*eslint no-param-reassign:0*/ // Allow for axios('example/url'[, config]) a la fetch API if (typeof config === 'string') { config = arguments[1] || {}; config.url = arguments[0]; } else { config = config || {}; } config = mergeConfig(this.defaults, config); // Set config.method if (config.method) { config.method = config.method.toLowerCase(); } else if (this.defaults.method) { config.method = this.defaults.method.toLowerCase(); } else { config.method = 'get'; } // filter out skipped interceptors 過濾攔截器 var requestInterceptorChain = []; var synchronousRequestInterceptors = true; // forEach方法在InterceptorManager文件中, 其本質仍是utils文件中的forEach方法, 參考axios源碼(三) this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { // interceptor就是this.handler的每一個元素, 參見InterceptorManager文件 if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { return; } synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); }); var responseInterceptorChain = []; this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { // 跟上面同樣 responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); }); var promise; if (!synchronousRequestInterceptors) { var chain = [dispatchRequest, undefined]; Array.prototype.unshift.apply(chain, requestInterceptorChain); // 添加到chain chain.concat(responseInterceptorChain); // 一個新的數組 promise = Promise.resolve(config); while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise; } var newConfig = config; while (requestInterceptorChain.length) { var onFulfilled = requestInterceptorChain.shift(); var onRejected = requestInterceptorChain.shift(); try { newConfig = onFulfilled(newConfig); } catch (error) { onRejected(error); break; } } try { promise = dispatchRequest(newConfig); } catch (error) { return Promise.reject(error); } while (responseInterceptorChain.length) { promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift()); } return promise; }; Axios.prototype.getUri = function getUri(config) { config = mergeConfig(this.defaults, config); return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); }; // Provide aliases for supported request methods 給請求的方法提供一個別名 utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { /*eslint func-names:0*/ Axios.prototype[method] = function(url, config) { return this.request(mergeConfig(config || {}, { method: method, url: url, data: (config || {}).data })); }; }); utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { /*eslint func-names:0*/ Axios.prototype[method] = function(url, data, config) { return this.request(mergeConfig(config || {}, { method: method, url: url, data: data })); }; }); module.exports = Axios;