源码分析axios(1)~源码分析、模拟axios的创建

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475
■ 查看源码发现,起初axios【instance=bind(Axios.prototype.request, context);】是一个函数,

但后续【 utils.extend(instance, Axios.prototype, context);】又给它添加上了一些方法属性。

axios 函数对象可以调用自身axios(config)发送请求也可以调用属性的方法axios.request(config)发送请求的原理:(看学习axios必知必会(2)https://blog.csdn.net/shan333/p/15836026.html)

一、源码分析axios的创建

1、查看axios的实例对象new Axios(defaultConfig);

① 在类Axios 发现有配置对象拦截器对象属性

② 在Axios.js 文件中,还发现Axios的原型:Axios.prototype动态添加了属性方法

requestgetUri

‘delete’, ‘get’, ‘head’, ‘options’,

‘post’, ‘put’, ‘patch’

■ axios的创建的源码:

// 通过配置创建 axios 函数
var axios = createInstance(defaults);

function createInstance(defaultConfig) {
    //创建一个实例对象 context 可以调用 get post put delete request
    var context = new Axios(defaultConfig);// context 不能当函数使用 
	……
}

//在 Axios 类内有属性 配置对象和拦截器对象
function Axios(instanceConfig) {
    //实例对象上的 defaults 属性为配置对象
    this.defaults = instanceConfig;
    //实例对象上有 interceptors 属性用来设置请求和响应拦截器
    this.interceptors = {
        request: new InterceptorManager(),
        response: new InterceptorManager()
    };
}

// 在Axios.js 文件中,还发现: 
Axios.prototype.request = function request(config) {
	……
}
Axios.prototype.getUri = function getUri(config) {
	……
}
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
    /*eslint func-names:0*/
    Axios.prototype[method] = function (url, config) {
	……
   }
}
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
    /*eslint func-names:0*/
    Axios.prototype[method] = function (url, data, config) {
	……
   }
}

2、接着是instance:

首先是通过方法bind将request方法赋值给instance(此时instance是一个函数变量);

然后,通过方法extends 将**Axios****.**prototype 上的方法添加到 instance身上(此时instance是一个

“函数对象”变量);还将实例对象content的属性(配置对象拦截器对象属性)添加到instance身上

■ axios的创建的源码:
function createInstance(defaultConfig) {
//创建Axios的实例对象 context 
    var context = new Axios(defaultConfig);//context 是实例对象,不能当函数使用 
//将request 方法的 this 指向 context 并返回新函数 (instance 与 Axios.prototype.request 代码一致)
    var instance = bind(Axios.prototype.request, context); //instance是函数,可以用作函数使用
//将Axios的原型 Axios.prototype 的方法都添加到 instance 函数身上
   utils.extend(instance, Axios.prototype, context); //instance是"函数对象",可当函数使用,也可当对象使用
//将实例对象content的方法和属性添加到 instance 函数身上
  utils.extend(instance, context);

  return instance;
}

■ bind函数:
//返回一个新的函数,并将新函数 this 绑定到一个对象身上
module.exports = 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);
    };
};

■ extend函数:
function extend(a, b, thisArg) {
    forEach(b, function assignValue(val, key) {
        if (thisArg && typeof val === 'function') {
            a[key] = bind(val, thisArg);
        } else {
            a[key] = val;
        }
    });
    return a;
}

二、模拟axios的创建

❀ 实现调用axios(config)自身发送请求、调用axios对象的方法属性 axios.request(config)发送请求


 <span class="hljs-comment">//构造函数</span>
 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Axios</span>(<span class="hljs-params">config</span>) </span>{
 <span class="hljs-comment">//初始化</span>
 <span class="hljs-built\_in">this</span>.defaults = config;<span class="hljs-comment">//default默认属性</span>
 <span class="hljs-built\_in">this</span>.intercepters = {
 <span class="hljs-attr">request</span>: {},
 <span class="hljs-attr">response</span>: {}
 }
 }

 <span class="hljs-comment">//为类的原型添加相关方法</span>
 Axios.prototype.request = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">config</span>) </span>{
 <span class="hljs-built\_in">console</span>.log(<span class="hljs-string">'发送ajax请求,请求类型:'</span> + config.method)
 }
 Axios.prototype.get = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">config</span>) </span>{
 <span class="hljs-keyword">return</span> <span class="hljs-built\_in">this</span>.request({<span class="hljs-attr">method</span>: <span class="hljs-string">'GET'</span>})
 }
 Axios.prototype.post = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">config</span>) </span>{
 <span class="hljs-keyword">return</span> <span class="hljs-built\_in">this</span>.request({<span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>})
 }

 <span class="hljs-comment">//声明函数</span>
 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createInstance</span>(<span class="hljs-params">config</span>) </span>{
 <span class="hljs-comment">//实例化一个对象</span>
 <span class="hljs-keyword">var</span> context = <span class="hljs-keyword">new</span> Axios(config); <span class="hljs-comment">//实例对象可以调用方法,例如 context.get() 但是不能直接当函数使用 context() ×</span>
 <span class="hljs-keyword">var</span> instance = Axios.prototype.request.bind(context);<span class="hljs-comment">//instance 是一个函数,并且可以 instance({}),</span>
 <span class="hljs-comment">//但是因为bind返回的是一个函数(一个拥有了Axios.prototype.request() 方法的函数,而instance的参数就是Axios的实例),所以不能 instance.get()</span>

 <span class="hljs-comment">//将Axios.prototype 对象中的方法添加到instance函数中,让instance拥有get、post、request等方法属性</span>
 <span class="hljs-built\_in">Object</span>.keys(Axios.prototype).forEach(<span class="hljs-function"><span class="hljs-params">key</span> =></span> {
 <span class="hljs-comment">// console.log(key); //修改this指向context</span>
 instance[key] = Axios.prototype[key].bind(context);
 })
<span class="hljs-comment">//总结一下,到此instance自身即相当于Axios原型的request方法,</span>
<span class="hljs-comment">//然后又给instance的属性添加了上了Axios原型的request、get、post方法属性</span>
<span class="hljs-comment">//然后调用instance自身或instance的方法属性时,修改了this指向context这个Axios实例对象</span>

<span class="hljs-comment">//为instance函数对象添加属性 default 与 intercetors</span>
 <span class="hljs-built\_in">Object</span>.keys(context).forEach(<span class="hljs-function"><span class="hljs-params">key</span> =></span> {
 instance[key] = context[key];
 })

 <span class="hljs-comment">// console.dir(instance);</span>
 <span class="hljs-keyword">return</span> instance;
 }

 <span class="hljs-comment">//测试一下axios的创建过程</span>
 <span class="hljs-keyword">let</span> axios = createInstance();
 <span class="hljs-comment">//发送Ajax请求</span>
 axios({<span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>});
 axios.post({});


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

[虚幻私塾】

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值