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

简介: 【10月更文挑战第13天】axios中的那些天才代码!看完我实力大涨!

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包含defaultsinterceptors属性,其对象原型__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的指向

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重新指向其实例化对象。

相关文章
|
6月前
【Axios】配置默认值及拦截器代码逐行详解
【Axios】配置默认值及拦截器代码逐行详解
77 0
|
11月前
|
数据处理
Axios 默认配置 简化URL 简化代码 多台服务器接口配置
Axios 默认配置 简化URL 简化代码 多台服务器接口配置
|
JavaScript 前端开发 安全
ts中的泛型与axios的一次相遇,这不工作效率和代码逼格一下子就上来了
ts中的泛型与axios的一次相遇,这不工作效率和代码逼格一下子就上来了
ts中的泛型与axios的一次相遇,这不工作效率和代码逼格一下子就上来了
|
1月前
|
资源调度 JavaScript
|
3月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
1月前
|
缓存 JavaScript 搜索推荐
|
3月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
2月前
|
JavaScript 前端开发 开发者
vue中使用axios请求post接口,请求会发送两次
vue中使用axios请求post接口,请求会发送两次
|
30天前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
85 4

热门文章

最新文章

  • 1
    若依修改,若依如何发送请求---王清江07,axios的请求在request.js文件中,若依发送GET请求,必须用param
    121
  • 2
    axios发送post请求,如何接受和返回一个axios的字段,解决bug的方法,困难的事情先从简单做起,先从发送一个axios的post请求做起,解决方法查别人的资料,查看F12看network就行
    42
  • 3
    文本,前后端数据交互,简单请求,如何去给data数据赋值,在mounted()里赋值,利用axios发送的请求,res就是数据集,就是后端的数据,this.users = res.data.data
    45
  • 4
    Request failed with status code 400,使用axios.post要发送参数,认真比对原项目,看看有没有忘记什么?
    84
  • 5
    vue3 在 watchEffect 里中断未完成的 axios 请求(只保留最后一次请求的方法---连续点击查询按钮的优化)
    119
  • 6
    前后端数据交互.js文件的axios的写法,想要往后端发送数据,页面注入API,await的意思是同步等待服务器数据,并返回,axios注入在其他页面,其他页面调用的时候,同步作用
    42
  • 7
    前后端数据交互,API风格组合式API和选项式API,setup是一个标识,组合式编写的意思,使定义count.value的值自增的写法,组合式API使用axios的写法,ref定义响应数据写法
    28
  • 8
    网页设计,若依项目修改(It must be done)02------axios封装后发get请求,axios请求的位置在呢?
    46
  • 9
    前后端数据交互之axios的路径怎样找?axios的路径是那个,是你打开Tomcat之后,出现的路径+你项目写的接口路径
    34
  • 10
    数据交互,前后端数据请求,axios请求,对象结构的使用,E6的使用,结构赋值是什么?函数形参的obj如何,函数形参的obj就改成对象结构接收传入的数据对象
    26