IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> axios 是如何封装 HTTP 请求的?,web全栈开发 -> 正文阅读

[网络协议]axios 是如何封装 HTTP 请求的?,web全栈开发




axios 中的 XHR 模块相对简单,它是对?`XMLHTTPRequest`?对象的封装,这里我就不再解释了。有兴趣的同学,可以自己阅读源源码看看,源码位于?`adapters/xhr.js`?文件中。



### 拦截器模块



现在让我们看看 axios 是如何处理,请求和响应拦截器函数的。这就涉及到了 axios 中的统一接口 ——`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;

};




这个函数是 axios 发送请求的接口。因为函数实现代码相当长,这里我会简单地讨论相关设计思想:



1.  `chain`?是一个执行队列。队列的初始值是一个携带配置(`config`)参数的 Promise 对象。

    

2.  在执行队列中,初始函数?`dispatchRequest`?用来发送请求,为了与?`dispatchRequest`对应,我们添加了一个?`undefined`。添加?`undefined`?的原因是需要给 Promise 提供成功和失败的回调函数,从下面代码里的?`promise = promise.then(chain.shift(), chain.shift());`?我们就能看出来。因此,函数?`dispatchRequest`?和?`undefiend`?可以看成是一对函数。

    

3.  在执行队列?`chain`?中,发送请求的?`dispatchReqeust`?函数处于中间位置。它前面是请求拦截器,使用?`unshift`?方法插入;它后面是响应拦截器,使用?`push`?方法插入,在?`dispatchRequest`?之后。需要注意的是,这些函数都是成对的,也就是一次会插入两个。

    



浏览上面的?`request`?函数代码,我们大致知道了怎样使用拦截器。下一步,来看看怎样撤销一个 HTTP 请求。



### 撤销请求模块



与撤销请求相关的模块位于?`Cancel/`?文件夹下,现在我们来看下相关核心代码。



首先,我们来看下基础?`Cancel`?类。它是一个用来记录撤销状态的类,具体代码如下:



function Cancel(message) {

this.message = message;

}

Cancel.prototype.toString = function toString() {

return ‘Cancel’ + (this.message ? ': ’ + this.message : ‘’);

};

Cancel.prototype.CANCEL = true;




使用?`CancelToken`?类时,需要向它传递一个 Promise 方法,用来实现 HTTP 请求的撤销,具体代码如下:



function CancelToken(executor) {

if (typeof executor !== 'function') {

    throw new TypeError('executor must be a function.');

}



var resolvePromise;

this.promise = new Promise(function promiseExecutor(resolve) {

    resolvePromise = resolve;

});



var token = this;

executor(function cancel(message) {

    if (token.reason) {

        return;

    }

    token.reason = new Cancel(message);

    resolvePromise(token.reason);

});

}

CancelToken.source = function source() {

var cancel;

var token = new CancelToken(function executor(c) {

    cancel = c;

});

return {

    token: token,

    cancel: cancel

};

};




`adapters/xhr.js`?文件中,撤销请求的地方是这样写的:



if (config.cancelToken) {

config.cancelToken.promise.then(function onCanceled(cancel) {

  if (!request) {

     return;

    }



    request.abort();

    reject(cancel);

    request = null;

});

}




通过上面的撤销 ?HTTP请求的例子,让我们简要地讨论一下相关的实现逻辑:



1.  在需要撤销的请求中,调用?`CancelToken`?类的?`source`?方法类进行初始化,会得到一个包含?`CancelToken`?类实例 A?和?`cancel`?方法的对象。

    

2.  当 source 方法正在返回实例 A 的时候,一个处于 pending 状态的?`promise`?对象初始化完成。在将实例 A 传递给 axios 之后,`promise`?就可以作为撤销请求的触发器使用了。

    

3.  当调用通过?`source`?方法返回的?`cancel`?方法后,实例 A 中?`promise`?状态从 pending 变成 fulfilled,然后立即触发?`then`?回调函数。于是 axios 的撤销方法——`request.abort()`?被触发了。

    



**axios 这样设计的好处是什么?**

---------------------



### 发送请求函数的处理逻辑



如前几章所述,axios 不将用来发送请求的?`dispatchRequest`?函数看做一个特殊函数。实际上,`dispatchRequest`?会被放在队列的中间位置,以便保证队列处理的一致性和代码的可读性。



### 适配器的处理逻辑



在适配器的处理逻辑上,`http`?和?`xhr`?模块(一个是在 Node.js 中用来发送请求的,一个是在浏览器里用来发送请求的)并没有在?`dispatchRequest`?函数中使用,而是各自作为单独的模块,默认通过?`defaults.js`?文件中的配置方法引入的。因此,它不仅确保了两个模块之间的低耦合,而且还为将来的用户提供了定制请求发送模块的空间。



### 撤销 HTTP 请求的逻辑



在撤销 HTTP 请求的逻辑中,axios 设计使用 Promise 来作为触发器,将?`resolve`?函数暴露在外面,并在回调函数里使用。它不仅确保了内部逻辑的一致性,而且还确保了在需要撤销请求时,不需要直接更改相关类的样例数据,以避免在很大程度上入侵其他模块。



**总结**

------





### 最后

中年危机是真实存在的,即便有技术傍身,还是难免对自己的生存能力产生质疑和焦虑,这些年职业发展,一直在寻求消除焦虑的依靠。

*   技术要深入到什么程度?

*   做久了技术总要转型管理?

*   我能做什么,我想做什么?

*   **一技之长,就是深耕你的专业技能,你的专业技术。**(重点)

*   独立做事,当你的一技之长达到一定深度的时候,需要开始思考如何独立做事。(创业)

*   拥有事业,选择一份使命,带领团队实现它。(创业)

**一技之长分五个层次**

*   栈内技术 - 是指你的前端专业领域技术

*   栈外技术 - 是指栈内技术的上下游,领域外的相关专业知识

*   工程经验 - 是建设专业技术体系的“解决方案”

*   带人做事 - 是对团队协作能力的要求

*   业界发声 - 工作经验总结对外分享,与他人交流



> 永远不要放弃一技之长,它值得你长期`信仰持有`。

**[CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](

)**

> 主要内容包括html,css,html5,css3,JavaScript,正则表达式,函数,BOM,DOM,jQuery,AJAX,vue 等等。

![](https://img-blog.csdnimg.cn/img_convert/44bc3d1e2743a7cf1e94e28026aedf8d.png)


> **本文已被[CodeChina开源项目:【一线大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://codechina.csdn.net/m0_60958482/web-p7)收录,自学编程路线及系列技术文章等资源持续更新中...**
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 19:10:26  更:2021-09-11 19:11:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:55:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码