目录结构
其中,lib/adapters 是具体发起请求的对象,分为两个文件 http.js
,xhr.js
;http 适用于 node.Js 环境; xhr.js 适用于 浏览器环境;
xhr.js 采用 XMLHttpRequest 对象创建,整体遵循 这个文件中的四步;
module.exports = function bind(fn, thisArg) { return function wrap() { console.log('arguments--==='); console.log(arguments); var args = new Array(arguments.length); for (var i = 0; i < args.length; i++) { args[i] = arguments[i]; } return fn.apply(thisArg, args); }; };
这个函数的作用是 用来,改变 fn 的执行的作用域的;
无效写法
import Vue from "vue"; import axios from "axios"; axios.defaults.timeout = 5000; //响应时间 axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=UTF-8"; axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; //配置接口地址 // 添加响应拦截器 axios.interceptors.response.use( function (res) { return res; }, function (error) { // 对响应错误做点什么 const err = error.response.data; if (err.status_code === 417) { alert(err.message); } else if (err.status_code === 422) { for (const item in err.errors) { alert(err.errors[item][0]); } } else { alert(err.message ? err.message : "提交失败"); } return Promise.resolve(error.response); } ); const instance = axios.create({ baseURL: process.env.VUE_APP_BASE_URL }) const socialInstance = axios.create({ baseURL: process.env.VUE_APP_SOCIAL_BASE_URL }) export default axios; Vue.prototype.$axios = instance; Vue.prototype.$socailAxios = socialInstance;
怎样优化,怎能实现上述的写法呢?
待解决
给 axios 更改参数的几种形式?
本质都是修改 axios 实例的 defaults 属性内容,而实现方式都是通过 Axios.prototype.request
来实现的;
通过实例 defaults 属性
axios.defaults.timeout=10000;
通过直接给实例传参
axios({ timeout:10000 })
通过 request 来配置
axios.request('/getUser',{ timeout:10000 })
通过 method 别名配置
axios.get('/getUser',{ timeout:10000 })
axios.create() 本身 是返回一个函数,怎样给这个函数 添加 诸如 interceptors 等属性?
通过如下
var context = new Axios(defaultConfig); var instance = bind(Axios.prototype.request, context); // Copy axios.prototype to instance utils.extend(instance, Axios.prototype, context); utils.extend(instance, context); return instance;
拦截器怎样触发的呢?
通过 promise 链
var chain = [dispatchRequest, undefined]; var promise = Promise.resolve(config); this.interceptors.request.forEach(function unshiftRequestInterceptors( interceptor ) { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); this.interceptors.response.forEach(function pushResponseInterceptors( interceptor ) { chain.push(interceptor.fulfilled, interceptor.rejected); }); while (chain.length) { promise = promise.then(chain.shift(), chain.shift()); } return promise;
通过上述代码,实现了类似如下效果:
Promise.resolve(config).then(interceptors.request).then(dispatchRequest).then(interceptors.response).then(...)
cancelToken 怎样实现 同一个 cancel token 取消多个请求的?
通过 cancelToken 这块的代码,对于面向对象编程理解深了一步;各个文件中间,通过暴露的接口进行 通信(比如 xhr.js 和 axios 各种配置的通信);面向对象可以更好的解释这个通信过程;而如果使用 面向过程的编程方式,估计会乱成一锅粥