Axios之Axios构造函数以及request

前言

在上一篇文章中分析了axios的实例创建实际上所有aixos请求的创建都是request方法来实现的。
在实际分析之前,先来梳理总结下axios创建请求的方式:

axios(config)
axios(url, config)
axios.create(config)
axios.request(config)
axios.get(url, config)
同理:delete,head, options与get相同
axios.post(url, data, config)
同理:put, patch与post相同


实际上,axios把Axios暴露出去了,你也可以同Axios来创建axios实例对象,调用request、get等定义在Axios原型上方法

上面就是axios所有请求支持,实际上上面所有请求都是调用request方法来实现的,而request方法是在core/Axios.js中定义的

具体分析

本篇文章分析Axios.js模块的实现功能,实际上Axios.js实现的功能主要是两块:

  • Axios实例创建、Axios.prototype.request方法定义、get等具体请求定义

  • 请求拦截器处理

Axios.js模块整个的处理流程如下:
Axios之Axios构造函数以及request_第1张图片

Axios构造函数

Axios构造函数中,创建两个实例属性,分别是defaults、interceptors

defaults表示配置对象,如果不是用户直接调用Axios,那这个属性值就是defaults.js模块暴露的默认值
interceptors:拦截器,定义了request和response拦截器属性分别表示请求和响应拦截器

this.interceptors = {
 // InterceptorManager就是拦截器对象构造函数
    request: new InterceptorManager(),
    response: new InterceptorManager()
  };
Axios.prototype.request

该方法是axios项目的核心处理方法,实现用户自定义配置、应用拦截器、发送请求核心功能

  // 支持axios(url, config)
  if (typeof config === 'string') {
    config = arguments[1] || {};
    config.url = arguments[0];
  } else {
    config = config || {};
  }

  // 应用自定义配置
  config = mergeConfig(this.defaults, config);
  // 如果method不存在,则默认get请求
  config.method = config.method ? config.method.toLowerCase() : 'get';

梳理拦截器位置

 // chain是一个数组,dispatchRequest是发送请求模块
  var chain = [dispatchRequest, undefined];

  // 请求拦截器处理
  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);
  });

实际上上面有个小技巧,就是通过chain数组模拟堆栈顺序,请求拦截器在发送请求前,响应拦截器在请求成功后,而实现这个效果就是通过数组的顺序来实现的,故:

request调用unshift将拦截器插入最前部
response调用push将拦截器推入尾部

发起请求并处理拦截器

var promise = Promise.resolve(config);
while(chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
}

实际上上面会形成链式,下一次promise依赖上一次promise的返回值

实例:

假设定义一个请求拦截器和一个响应拦截器

//添加请求拦截器
axios.interceptors.request.usefunctionconfig){
     return config;
   },functionerror){
     //请求错误时做些事
     return Promise.reject(error);
   });

//添加响应拦截器
axios.interceptors.response.usefunctionresponse){
     return response;
   },functionerror){
     //请求错误时做些事
     return Promise.reject(error);
   });

此时再来看chain,实际上会有如下元素:

[requestResolveFn, requestRejectFn, dispatchRequest, undefined, responseResolveFn, responseRejectFn]

再执行上面的循环:

  1. 第一次Promise总是resolve, 所以执行requestResoveFn
  2. requestResoveFn返回结果是resolve,所以dispatchRequest
  3. dispatchRequest是发送请求的模块,若reslove则调用responseResolveFn,若reject,则responseRejectFn

总结

request中需要关注的点有两个:

  • 请求和响应拦截器的位置的处理

  • while循环处理promise的链式

下一篇文章将分析dispatchRequest模块的实现逻辑(这是发送请求的模块)。

你可能感兴趣的:(Vue相关)