专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
前端早读课  ·  【第3452期】React 开发中使用开闭原则 ·  6 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  17 小时前  
前端早读课  ·  【第3451期】前端 TypeError ... ·  昨天  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
51好读  ›  专栏  ›  前端大全

axios中的那些天才代码!看完我实力大涨!

前端大全  · 公众号  · 前端  · 2024-08-19 11:50

正文

作者:林恒

https://www.cnblogs.com/smileZAZ/p/18330636


axios的两种调用方式

经常调接口的同学一定非常熟悉aixos下面的两种使用方式:

  • axios(config)
// 配置式请求
axios({
  method'post',
  url'/user/12345',
});
  • axios.post(url, config)
// 简洁的写法
axios.post('/user/12345')

不知道各位大佬有没有思考过这样的问题:

axios到底是个什么东西?我们为什么可以使用这两种方式请求接口呢?axios是怎么设计的?

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是如何实现的呢?

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的源码

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的指向







请到「今天看啥」查看全文