1.创建构造函数
原始构造函数用于存储默认属性与拦截器操作
拦截器管理器构造函数InterceptorManager 主要是为了存储拦截器的失败与成功操作函数
function Axios(config) {// 数据初始化this.defaults = config // 默认属性this.intercepters = { // 拦截器操作request: new InterceptorManager(), // 用于请求前拦截response: new InterceptorManager(), // 用于响应结果拦截}
}
2.创建Axios构造函数的原型方法(get,post,request)
重点是request函数,主要是用promise来进行链式操作
创造promise
chain存储axios请求函数dispatchRequest,undefined(失败占位符)
请求拦截在头部插入
响应拦截在尾部插入
真实axios请求在(请求拦截)与(响应拦截)之间
先执行请求拦截再执行真是axios请求,最后执行响应拦截
while 保证全部执行
// 创建原型方法Axios.prototype.get = function (config) {return this.request({ ...config, method: 'GET', })
}Axios.prototype.post = function (config) {return this.request({ ...config, method: 'POST' })
}Axios.prototype.request = function (config) {console.log('发送 AJAX 请求 请求的类型为 ' + config.method);// 发送请求// 创建promise对象let promise = Promise.resolve(config);//发送请求let chain = [dispatchRequest, undefined];//undefined进行占位// 请求拦截this.intercepters.request.handlers.forEach(item => {//头部插入,后写入的先执行chain.unshift(item.fulfilled, item.injected)})// debugger//响应拦截器this.intercepters.response.handlers.forEach(item => {//尾部插入,后写入的后执行chain.push(item.fulfilled, item.rejected);});//遍历while (chain.length > 0) {//保证全部执行,成功函数,失败函数promise = promise.then(chain.shift(), chain.shift());}return promise;
}
3.创建dispatchRequest 函数
function dispatchRequest(config) {return xhrRequest(config).then(response => {//响应的结果进行转换处理//....return response;}, error => {throw error;});
}
4. xhrRequest发送请求
promise进行xhr请求
当存在cancelToken的时候进行取消操作
promise.then的执行时机是在cancel方法改变promise状态才执行
function xhrRequest(config) {return new Promise((reslove, inject) => {let xhr = new XMLHttpRequest();xhr.open(config.method, config.url)xhr.send();xhr.onreadystatechange = function () {if (xhr.readyState == 4) {if (xhr.status == 200 && xhr.status < 300) {reslove({config: config,data: xhr.response,Headers: xhr.getAllResponseHeaders(),request: xhr,status: xhr.status,statusText: xhr.statusText})} else {inject(new Error('请求失败 失败的状态码为' + xhr.status))}}}//关于取消请求的处理if (config.cancelToken) {//对 cancelToken 对象身上的 promise 对象指定成功的回调config.cancelToken.promise.then(value => {xhr.abort();console.log('请求已经被取消')//将整体结果设置为失败inject(new Error('请求已经被取消'))});}})
}
6.拦截器管理器构造函数
function InterceptorManager() {this.handlers = [];
}
InterceptorManager.prototype.use = function (fulfilled, rejected) {this.handlers.push({fulfilled,rejected})
}
7.创建axios声明函数,生成axios,并将Axios的原型方法跟默认属性添加到axios上
function createInstance(config) {// 实例化一个对象 , bind绑定this而不执行let context = new Axios(config)let instance = Axios.prototype.request.bind(context);// console.log(instance)// 将context的原型方法添加到instance上Object.keys(Axios.prototype).forEach(key => {instance[key] = Axios.prototype[key].bind(context)})// 将context中的default 与intercepters添加到instance上Object.keys(context).forEach(key => {instance[key] = context[key]})// console.dir(instance)return instance;
}
8.绑定拦截器事件
axios.intercepters.request.use(function one(config) {console.log('请求拦截器 成功 - 1号');return config;
}, function one(error) {console.log('请求拦截器 失败 - 1号');return Promise.reject(error);
});axios.intercepters.request.use(function two(config) {console.log('请求拦截器 成功 - 2号');return config;
}, function two(error) {console.log('请求拦截器 失败 - 2号');return Promise.reject(error);
});// 设置响应拦截器
axios.intercepters.response.use(function (response) {console.log('响应拦截器 成功 1号');return response;
}, function (error) {console.log('响应拦截器 失败 1号')return Promise.reject(error);
});axios.intercepters.response.use(function (response) {console.log('响应拦截器 成功 2号')return response;
}, function (error) {console.log('响应拦截器 失败 2号')return Promise.reject(error);
});
9. CancelToken 构造函数用来取消请求
创造promise,先不执行resolve成功函数,而是将resolve存储起来,将function(){resolvePromise();}作为参数传递给cancel
function CancelToken(executor){//声明一个变量var resolvePromise;//为实例对象添加属性this.promise = new Promise((resolve) => {//将 resolve 赋值给 resolvePromiseresolvePromise = resolve});console.log(this.promise,'this.promise')//调用 executor 函数executor(function(){//执行 resolvePromise 函数resolvePromise();});
}
使用
axios取消请求
上一篇:什么新月四字成语
下一篇:趔趔趄趄的四字近义词