axios源码分析

基本使用

了解一款常见的网络框架原理axios,通过适配器模式,在浏览器封装xhr,在node封装http模块,上层的调用保持一致。

需要掌握

  • 请求拦截器和响应拦截器的实现
  • 基于axios进行二次封装,实现业务特定需求
  • 并发限制
  • 用户鉴权认证、JWT

常见问题

  • 如何取消请求:构造cancelToken然后传入请求配置参数,然后可以在发送请求之前手动调用该CancelToken对象的calcel方法来抛出异常,取消本次请求,Promise本身是无法取消的
  • 拦截器是如何实现的:先构造一个队列,将请求拦截器依次放在队列头部,响应拦截器一次放在队列尾部,中间是dispatchRequest方法,然后将该队列构造为promise链式调用。

拦截器

构造函数

function Axios(instanceConfig) {
  this.defaults = instanceConfig;
  this.interceptors = {
    request: new InterceptorManager(),
    response: new InterceptorManager()
  };
}
然后来看看`InterceptorManager`这个拦截器管理类
function InterceptorManager() {
  this.handlers = [];
}
// 添加拦截器
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
  this.handlers.push({
    fulfilled: fulfilled,
    rejected: rejected
  });
  return this.handlers.length - 1;
};
// 取消拦截器
InterceptorManager.prototype.eject = function eject(id) {
  if (this.handlers[id]) {
    this.handlers[id] = null;
  }
};
// 遍历拦截器
InterceptorManager.prototype.forEach = function forEach(fn) {
  utils.forEach(this.handlers, function forEachHandler(h) {
    if (h !== null) {
      fn(h);
    }
  });
};
核心方法`Axios.prototype.request`
 Axios.prototype.request = function request(config) {
    // ...初始化配置

    // 构建任务链
  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;
};
理解拦截器也十分容易了

// 原始的接口
function dispatchRequest(config){
    let res = {
        params: config,
        code: 200,
        data: "hello response",
    }
    // 省略实际接口请求逻辑
    return Promise.resolve(res);
}
var chain = [dispatchRequest, undefined];

// 请求配置
var config = {
    headers: {
        'x-token': 'xxxx12token'
    },
    params: {
        id: 1
    }
};
var promise = Promise.resolve(config);

var interceptors = {
    request: [
        {
            fulfilled(config) {
                console.log(config);
                return config;
            },
            rejected() {
                console.log("request reject");
            }
        }
    ],
    response: [
        {
            fulfilled(res) {
                console.log(res)
            },
            rejected() {
                console.log("response reject");
            }
        }
    ]
};

interceptors.request.forEach(function unshiftRequestInterceptors(
     interceptor
 ) {
     chain.unshift(interceptor.fulfilled, interceptor.rejected);
 });

interceptors.response.forEach(function pushResponseInterceptors(
     interceptor
 ) {
     chain.push(interceptor.fulfilled, interceptor.rejected);
 });

while (chain.length) {
    promise = promise.then(chain.shift(), chain.shift());
}

promise.then(res=>{
    console.log(res)
})

取消请求

axios源码分析的相似文章

案例+图解带你一文读懂Canvas🔥🔥(2W+字)分析巧用 -webkit-box-reflect 倒影实现各类动效分析web代码编辑器有哪些,WEB代码编辑器哪家强分析css滚动条样式代码,实现一个渐变的滚动条分析vue踩坑记录,巨坑巨坑巨坑 记录一下以防下次遇到分析一些有趣的 JavaScript 和 CSS 库分析个人 echarts踩坑记录分析毛玻璃特效,backdrop-filter,让你的网站熠熠生”毛’分析浅谈前端的状态管理分析波浪形动画效果,波浪动画很常见,但这个波浪组件绝对不常见分析