/ javaScript

axios -- 9:axios axios库对外暴露的函数

console.info

该系类文章旨在研究 axios 的实现。在研究源码的基础上,去理解 AXISO 是如何实现 AJAX 请求并更好的去使用这个库。

对外暴露的 axios 方法

对应文件为 lib/axios.js

终于写到了最后,这个文件主要是对外保留 axios 方法,主要内容包括实例化 Axios 对象,在此方法下绑定一些公用的方法。

实例化 Axios 对象

对应代码为:

function createInstance(defaultConfig) {
  var context = new Axios(defaultConfig);
  // 绑定 Axios.prototype.request 到新实例化出来的对象上
  // 这里为什么需要这么写在下面有解释
  var instance = bind(Axios.prototype.request, context);

  // 将 Axios 类下的方法绑定到 instance 对象上
  // extend 函数的第三个参数为方法执行的上下文环境
  utils.extend(instance, Axios.prototype, context);

  // 将实例化出来的 context 对象下的属性绑定到 instance 上
  utils.extend(instance, context);

 // 返回
  return instance;
}

var axios = createInstance(defaults);
// 对外保留 axios 方法
module.exports = axios;

在刚开始看这段代码时,我想大多数人和我一样,会困惑,直接实例化一个 Axios 对象返回出来不就好了么?为什么要重新生成一个 instance 函数,让这个函数拥有 Axios 类下面的方法,以及实例化出来的 context 对象下的属性。

在仔细看了 bind 函数后,我知道了答案

function bind(fn, thisArg) {
    return function wrap() {
        var args = new Array(arguments.length);
        for (var i = 0; i < args.length; i++) {
            args[i] = arguments[i];
        }
        return fn.apply(thisArg, args);
    };
}
/*
* eg:
* var fn = function(c, d){
*   console.log(this.a + this.b + c + d);
* }
* bind(fn, {a: 1,b: 2})(3, 4) => 10
*
* */

这个就是 bind 的方法了,咋一看无非就是绑定函数上下文环境的作用,但是,如果深究下去,就会发现,这个传入 bind 方法里的函数是不能再次更换函数上下文环境了。因此在第一遍看这个方法时我写下了这么一段注释

更加灵活的使用函数,临时绑定函数作用域以及函数参数

而在第二遍看这段函数时,我又添加了一句

确保函数在指定的作用域中执行

这就是为什么需要重新生成一个 instance 这个 instance 的方法永远只能在指定的上下文环境下执行(也就是代码中的 context ),而之后的第一段段 extend 无非就是添加了 axios.get 等一些在 Axios 下定义的快捷方法,而第二段无非就是添加了 Axios 实例化类 context 中的 interceptors ,让 instance 拥有处理请求和响应的能力。

人的思想果然是伟大的,妙,实在是妙。

绑定一些公有的方法

// 对外暴露 Axios 类对象
axios.Axios = Axios;
// 对外暴露 createInstance 方法,以便生成另一个 axios 对象
axios.create = function create(instanceConfig) {
  return createInstance(utils.merge(defaults, instanceConfig));
};
// 暴露取消函数,在 config 配置 cancelToken 中有用到,用于主动取消请求
axios.Cancel = require('./cancel/Cancel');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel');
// 暴露 all 方法
axios.all = function all(promises) {
  return Promise.all(promises);
};

总结

关于 axios 这个请求库到此也就结束了,收益良多,有关于编程思想的,也有关于浏览器一些默认对象的,相信在今后在用这个库也能更加的得心应手。

最后赋上 Axios 的文件关系。
image