..
点击关注公众号,“技术干货”及时达!axios的两种调用方式经常调接口的同学一定非常熟悉aixos下面的两种使用方式:axios(config)// 配置式请求axios({ method: ‘post‘, url: ‘/user/12...
A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!
经常调接口的同学一定非常熟悉aixos下面的两种使用方式:
axios(config)
// 配置式请求
axios({
method: 'post',
url: '/user/12345',
});
axios.post(url, config)
// 简洁的写法
axios.post('/user/12345')
不知道各位大佬有没有思考过这样的问题:
axios到底是个什么东西?我们为什么可以使用这两种方式请求接口呢?axios是怎么设计的?
为了搞明白上面的问题,我们先按照传统思路仿照axios源码实现一个简单的axios。
function Axios(config){
this.defaults = config; // 配置对象
this.interceptors = { // 拦截器对象
request:{},
response:{}
}
}
上面的代码中,我们实现了一个基本的Axios类,但它还不具备任何功能。我们现在给它添加功能。
Axios.prototype.request = function(config){
console.log('发送Ajax 请求 type:' +config.method)
}
Axios.prototype.get = function(){
return this.request({method:'GET'})
}
Axios.prototype.post = function(){
return this.request({method: 'POST'})
}
上面的代码中,我们在request属性上创建了一个通用的接口请求方法,get和post实际都调用了request,但内部传递了不同的参数,这和axios(config)、axios.post()有异曲同工之妙。
参考aixos的用法, 现在,我们需要创建实例对象
let aixos = new Axios(config)
创建后的axios包含defaults
和interceptors
属性,其对象原型__proto__
上(指向Axios的prototype)包含request、get及post方法,因此,我们现在可以使用aixos.post()
的方法模拟调用接口了。
但注意,此时aixos只是一个实例对象,不是一个函数!我们似乎也没办法做到改造代码使用aixos(config)
的形式调用接口!
aixos是如何实现的呢?
为了即能使用axios(config)又能使用axios.get(),axios的核心伪逻辑如下
function Axios(config){
this.defaults = config; // 配置对象
this.interceptors = { // 拦截器对象
request:{},
response:{}
}
}
Axios.prototype.request = function(config){
console.log('发送Ajax 请求 type:' +config.method)
}
Axios.prototype.get = function(){
return this.request({method:'GET'})
}
Axios.prototype.post = function(){
return this.request({method: 'POST'})
}
function createInstance(config) {
//注意instance是函数
const instance = Axios.prototype.request;
instance.get = Axios.prototype.get
instance.post = Axios.prototype.post
return instance;
}
let axios = createInstance();
通过上述的伪代码,我们可以知道axios是createInstance()函数的返回值instance。
instance 是一个函数,因此,axios也是一个函数,可以使用axios(config);
instance也是一个对象(js万物皆对象),其原型上有get方法和post方法,因此,我们可以使用axios.post()。
我们看看aixos的源码
function createInstance(config) {
//实例化一个对象
var context = new Axios(config); //但是不能直接当函数使用
var instance = Axios.prototype.request.bind(context);
//instance 是一个函数,并且可以 instance({}),
//将Axios.prototype 对象中的方法添加到instance函数中,让instance拥有get、post、request等方法属性
Object.keys(Axios.prototype).forEach(key => {
// console.log(key); //修改this指向context
instance[key] = Axios.prototype[key].bind(context);
})
//总结一下,到此instance自身即相当于Axios原型的request方法,
//然后又给instance的属性添加了上了Axios原型的request、get、post方法属性
//然后调用instance自身或instance的方法属性时,修改了this指向context这个Axios实例对象
//为instance函数对象添加属性 default 与 intercetors
Object.keys(context).forEach(key => {
instance[key] = context[key];
})
return instance;
}
可以说,上面的代码真的写的精妙绝伦啊!
注意这里,为什么要修改this的指向
var instance = Axios.prototype.request.bind(context);
首先,requset 是Axios原型对象上的方法,其方法内部的this指向的是其实例化对象context!
Axios.prototype.request = function request(config) {
/*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';
}
// Hook up interceptors middleware
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;
};
因此,如果我们直接使用Axios.prototype.request()
就会出现问题,因为这事reques方法内部的this会指向错误,导致函数不能运行,因此,我们必须将this重新指向其实例化对象。
A股板块轮动加剧,跨年大妖来袭,这几只票主力已明显介入!微信搜索关注【研讯小组】公众号(可长按复制),回复666,领取代码!
本站内容转载请注明来源并提供链接,数据来自互联网,仅供参考。如发现侵权行为,请联系我们删除涉嫌侵权内容。
【封装axios】前端架构让你一次封装终身受益!!!(稀土掘金技术社区2024年11月07日文章)
axios中的那些天才代码!看完我实力大涨!(稀土掘金技术社区2024年10月07日文章)
前端部署后自动提醒用户更新(稀土掘金技术社区2024年11月09日文章)
用iframe必定遇到过这六种“坑”之一(以vue为示例)(稀土掘金技术社区2024年11月05日文章)
vue3+gasp实现【星之卡比输入框】(稀土掘金技术社区2024年10月23日文章)
flex 布局中更巧妙的布局方案!比 justify-content 和 align-items 好用多了!(稀土掘金技术社区2024年10月29日文章)
2024年了,前端人是时候给予页面一点 Hero Section 魔法了!!! (Three.js)(稀土掘金技术社区2024年10月05日文章)
发现一个程序员最强外设,助你高效开发早日摸鱼!(稀土掘金技术社区2024年09月24日文章)
源码视角,Vue3为什么推荐使用ref而不是reactive(稀土掘金技术社区2024年07月31日文章)
前端开发,vue3实现excel文件预览和打印(稀土掘金技术社区2024年08月05日文章)
版权投诉请发邮件到1191009458#qq.com(把#改成@),我们会尽快处理
Copyright©2023-2024众股360(www.zgu360.com).AllReserved|备案号:湘ICP备2023009521号-3
本站资源均收集整理于互联网,其著作权归原作者所有,如有侵犯你的版权,请来信告知,我们将及时下架删除相应资源
Copyright © 2024-2024 EYOUCMS. 易优CMS 版权所有 Powered by EyouCms