关于我对axios的源码理解
admin
2024-02-10 09:24:41

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取消请求

相关内容

热门资讯

他为何要选择江铃轻客?——马好... 当多辆豪华座驾停在车库积灰,马好好却独选江铃轻客,历时两年穿越8.7万公里,足迹遍布欧亚35个国家。...
日均437万通来电,12345... ▲北京市12345市民热线服务中心,话务人员正在坐席前忙碌。新京报记者 王子诚 摄 2025年12月...
养老金入市对股市影响 养老金入... 养老金入市对养老金保值增值和股市有何影响?国务院印发《基本养老保险基金投资管理办法》国务院8月23日...
养老金 入市时间 养老金 入市... 养老金入市方案已提交国务院 颁布进入倒计时据《证券日报》报道,8月12日,一位接近人力资源和社会保障...
养老金进入股市 养老金进入股市... 养老金入市股票比例不超3成 将长期利好股市养老基金实行中央集中运营、市场化投资运作。目前只在境内投资...