资讯专栏INFORMATION COLUMN

axios源码阅读

snifes / 815人阅读

摘要:响应的拦截器接收到的是对象至此,我们已经把的核心逻辑阅读完毕,从中我们也可以看到的易用性和可拓展性非常强。尤其是可拓展性,发送请求到接收响应的过程中的所有部分几乎都是可拓展的,尤其是,,留下了很多想象的空间。

为了方便使用,axios对象既能做对象使用,又能做函数使用.

axios.post("/user", {
    firstName: "Fred",
    lastName: "Flintstone"
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  
axios({
  method: "post",
  url: "/user/12345",
  data: {
    firstName: "Fred",
    lastName: "Flintstone"
  }
});

这一点axios是如何做到的,可以看到instance其实是一个绑定this的函数,调用axios就是调用context.request

function createInstance(){
    // 能当做函数使用的秘密
    var instance = bind(Axios.prototype.request, context);
    // 能当做对象使用的秘密
    utils.extend(instance, Axios.prototype, context);
    // 要拿到构造函数继承的属性
    utils.extend(instance, context);
    return instance
}

var axios = createInstance(defaults);

接下来我们看一下request方法,所有http请求的发送都会调用Axios.prototype.request,这个函数可以认为是整个axios的骨架,非常重要。

Axios.prototype.request = function request(config) {
    // 每个请求都会重新合成一个config,所以通过操作config对象,你可以标识请求,做某些操作,事实上每个axios的拦截器都能拿到config对象
    config = utils.merge(defaults, this.defaults, { method: "get" }, 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;
}

从拦截器中的主要逻辑,我们可以得到以下几点:

发送请求的整个执行顺序是,requestInterceptors ——》dispatchRequest ——》responseInterceptors

拦截器最初接收的对象是config,axios使用中也规定,请求的拦截器必须要返回config,这也是每个请求拦截器的函数参数是config的原因

拦截器的执行顺序与interceptors.request.use(function () {/*...*/})执行的顺序有关,即先use的请求拦截器会先执行。

如果拦截器中的函数时async函数,会阻塞整个拦截器链的执行,而transformData不会,所以如果需要对请求的数据做异步处理的话,要在拦截器中完成。

看一下,不同的http method是怎么复用request方法的

utils.forEach(["delete", "get", "head", "options"], function forEachMethodNoData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url
    }));
  };
});

utils.forEach(["post", "put", "patch"], function forEachMethodWithData(method) {
  /*eslint func-names:0*/
  Axios.prototype[method] = function(url, data, config) {
    return this.request(utils.merge(config || {}, {
      method: method,
      url: url,
      data: data
    }));
  };
});

接下来我们看dispatchRequest的核心逻辑:

// 处理config...

var adapter = config.adapter || defaults.adapter;

return adapter(config).then(function onAdapterResolution(response) {
throwIfCancellationRequested(config);

// Transform response data
response.data = transformData(
  response.data,
  response.headers,
  config.transformResponse
);

return response;
}, function onAdapterRejection(reason) {
if (!isCancel(reason)) {
  throwIfCancellationRequested(config);

  // Transform response data
  if (reason && reason.response) {
    reason.response.data = transformData(
      reason.response.data,
      reason.response.headers,
      config.transformResponse
    );
  }
}

return Promise.reject(reason);
});

可以看到dispatchRequest的核心逻辑大概有三步

处理config

使用adapter发送请求,axios默认内置两个adapter,一个是负责在brower发送请求的,一个是负责在node端发送请求,可以在根文件的defaults下看到

构造响应数据

所以通过dispatchRequest方法的阅读,我们可以得到以下启示:

adapter是可以替换的,所以如果你觉得你的xhr或http的逻辑更适合业务的需要,完全可以替换掉,你也完全可以开发出第三种adapter以处理特定情况,比如开发一个处理缓存的adapter,事实上我现在的项目就是这样做的。

响应的拦截器接收到的是response对象

至此,我们已经把axios的核心逻辑阅读完毕,从中我们也可以看到axios的易用性和可拓展性非常强。

尤其是可拓展性,发送请求到接收响应的过程中的所有部分几乎都是可拓展的,尤其是config,adapter,interceptor留下了很多想象的空间。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95113.html

相关文章

  • axios源码阅读(一)

    摘要:开始研究核心代码这个类首先是构造函数看完上面的内容大家应该有点印象,上挂了和,是默认的配置,顾名思义就是拦截器,目测包含了和两种类型。喜欢就点个赞吧参考文章源代码重点难点分析源代码重点难点分析 axios是一个基于promise的http库,支持浏览器和node端,最近我在做beauty-we的api设计,研读一个成熟的http库势在必行,axios功能完整、api简洁、注释清晰,再适...

    k00baa 评论0 收藏0
  • 记一次eggjs+axios传输multipart的纠错过程

    摘要:总所周知,的策略让每次都要发送码验证,为了方便,我在的里作了前置拦截。结果不幸从此发生最开始没有看官方文档,以为应该加在里面,又没有考虑到要上传格式的文档,所以直接结果发送的是。这很正常,阅读源码知为时会自动添加的头。不加又以上传了。 总所周知,egg的csrf策略让post每次都要发送token码验证,为了方便,我在axios的interceptor里作了前置拦截。 结果不幸从此发生...

    CarterLi 评论0 收藏0
  • Axios源码深度剖析 - AJAX新王者

    摘要:我们先来看看构造函数构造函数就是用来实现拦截器的,这个构造函数原型上有个方法。关于源码,其实是比较简单的,都是用来操作该构造函数的实例属性的。存放拦截器方法,数组内每一项都是有两个属性的对象,两个属性分别对应成功和失败后执行的函数。 Axios源码分析 - XHR篇 文章源码托管在github上,欢迎fork指正! axios 是一个基于 Promise 的http请求库,可以用在浏览...

    DangoSky 评论0 收藏0
  • Vue2.0—仿知乎日报总结

    摘要:一个基于全家桶开发的仿知乎日报单页应用项目地址源码地址项目在线地址在线地址模式下推荐使用移动端模式浏览去观看如果觉得做得还不错或者项目源码对您有帮助希望您小抬右手到右上角点一个您的支持是作者长期更新维护的动力项目起源从二月份开始学习学习了 Vue-News 一个基于vue全家桶开发的仿知乎日报单页应用 项目github地址:源码地址 项目在线地址:在线地址 (PC模式下推荐使用chro...

    lentoo 评论0 收藏0
  • sau交流学习社区--看小说的lovebook一个无线端BS应用

    摘要:爱上阅读,是一款的读小说等书籍的并且阅读的应用。找了好久发现发现只有追书神器的暴露出来了,起点之类的找不到。八最后最后打个小广告源码都已在上开源,目前在逐步完善功能中。欢迎感兴趣的同学和。 loveBook loveBook爱上阅读,是一款webapp的读小说等书籍的并且阅读的应用。如果觉得可以,欢迎fork和star。 自己最近在追斗破苍穹电视剧,下班时候在地铁上总听到有人说,斗破苍...

    leeon 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<