(Ajax)axios源码简析(三)——请求与取消请求

传送门:

  • axios源码简析(一)——axios入口文件
  • axios源码简析(二)——Axios类与拦截器
  • axios源码简析(三)——请求与取消请求

请求过程

Axios.prototype.request中我们看到,要先通过请求拦截器,才能进行请求。下面看一下dispatchRequest()是如何实现的

// /lib/core/dispatchRequest.jsmodule.exports = function dispatchRequest(config) {// 判断是否已经取消请求throwIfCancellationRequested(config);/* 对请求的url、headers、data进行处理 */// 发动请求的函数,返回一个promisevar adapter = config.adapter || defaults.adapter;return adapter(config).then(function onAdapterResolution(response) {// 判断是否已经取消请求throwIfCancellationRequested(config);// 处理返回的数据response.data = transformData(response.data,response.headers,config.transformResponse);return response;}, function onAdapterRejection(reason) {if (!isCancel(reason)) {// 判断是否已经取消请求throwIfCancellationRequested(config);// 处理返回的错误信息if (reason && reason.response) {reason.response.data = transformData(reason.response.data,reason.response.headers,config.transformResponse);}}return Promise.reject(reason);});

如果用户有在配置中传入adapter,将使用defaults.adapter,根据运行环境是浏览器还是nodejs采取不同的请求方式。

// /lib/defaults.js
function getDefaultAdapter() {var adapter;if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {// nodejs环境adapter = require('./adapters/http');} else if (typeof XMLHttpRequest !== 'undefined') {// 浏览器环境adapter = require('./adapters/xhr');}return adapter;
}var defaults = {adapter: getDefaultAdapter(),/* 其他配置 */
};modules.exports = defaults;

/lib/adapters/http.js/lib/adapters/xhr.js两个文件导出的函数都返回一个promise,具体的实现方式就不分析了。里面有很多http请求的细节,可以仔细研究。

取消请求

官方文档中的调用方法

const CancelToken = axios.CancelToken;
const source = CancelToken.source();axios.get('/user/12345', {cancelToken: source.token
}).catch(function(thrown) {if (axios.isCancel(thrown)) {console.log('Request canceled', thrown.message);} else {// handle error}
});axios.post('/user/12345', {name: 'new name'
}, {cancelToken: source.token
})// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

我们进入CancelToken类,找到了CancelToken.source()方法:

// /lib/cancel/CancelTokenCancelToken.source = function source() {var cancel;var token = new CancelToken(function executor(c) {cancel = c;});return {token: token,cancel: cancel};
};

可以看出,CancelToken.source().token是一个CancelToken类的实例,CancelToken.source().cancelnew CacelToken()时传入参数(一个函数)的参数(也是个函数),通过CancelToken的构造函数可以看出:

// /lib/cancel/CancelTokenfunction 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) {// Cancellation has already been requestedreturn;}token.reason = new Cancel(message);resolvePromise(token.reason);});
}

CancelToken.source().cancel就是这个函数:

function cancel(message) {if (token.reason) {// Cancellation has already been requestedreturn;}token.reason = new Cancel(message);resolvePromise(token.reason);
}

CancelToken.source().tokenpromisereason两个属性,promise 一直处于 pending状态,reason属性是一个Cancel类的实例,Cancel类的构造函数如下:

// /lib/cancel/Cancel.js
function Cancel(message) {this.message = message;
}Cancel.prototype.toString = function toString() {return 'Cancel' + (this.message ? ': ' + this.message : '');
};Cancel.prototype.__CANCEL__ = true;

在源码中,有以下几种方式检测是否执行了取消请求。
1 检测config.cancelToken是否有reason属性,如果有,将reason抛出,axios进入rejected状态。

// /lib/core/dispatchRequest.js
function throwIfCancellationRequested(config) {if (config.cancelToken) {config.cancelToken.throwIfRequested();}
}module.exports = function dispatchRequest(config) {// 判断是否已经取消请求throwIfCancellationRequested(config);/* ... */
};// /lib/cancel/CancelToken
CancelToken.prototype.throwIfRequested = function throwIfRequested() {if (this.reason) {throw this.reason;}
};

2 在请求过程中,执行CancelToken.source().tokenpromise属性中的resolve函数,参数是CancelToken.source().token.reason,并将其抛出,promise进入rejected状态

if (config.cancelToken) {// Handle cancellationconfig.cancelToken.promise.then(function onCanceled(cancel) {if (!request) {return;}// 取消请求request.abort();// promise进入rejectedreject(cancel);// Clean up requestrequest = null;});
}

调用方法中catch接到的thrown,就是CancelToken.source().token.reason

如果在使用axios时候,只在config中添加{cancelToken: source.token},而不调用source.cancel(),则CancelToken.source().token不会有reason属性,CancelToken.source().token.promise也一直是pending状态。请求不会取消。

参考

深入浅出 axios 源码
axios源码分析——取消请求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows配置tomcat环境

1、安装JDK 参考教程: https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.htmlCLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarCLASSPATH这个环境变量一定要配好,否则tomcat起不来,直接复制上面的内容,…

java 抽奖 高并发处理_如何设计高并发下的抽奖?

关于抽奖,需要考虑的点有很多,这里稍微整理了下主要需要考虑以下三点:用户抽奖次数限制奖品数量限制奖品发放的分布中奖的概率的可控性用户抽象次数限制一个用户必须限制抽奖的次数,而同一个用户的并发几率其实是很小的,所以这里可以用悲观锁来控制用户的抽奖次数。奖品数量限制…

WPF圆角按钮与触发颜色变化

原文:WPF圆角按钮与触发颜色变化<Button x:Name"button1" Content"按钮1" Margin"10,10,0,0" Cursor"Pen"><Button.Template><ControlTemplate><Border CornerRadius"15,15,15,15"><Border.Back…

咖啡豆的励志故事

好多年前就听过这个故事&#xff0c;以前没感触&#xff0c;最近特有感触。

PowerDesigner V16.5 安装教程以及汉化(数据库建模)

原文地址&#xff1a;https://blog.csdn.net/tgbyn/article/details/72809116 ----------------------------------------------------------------------一、power designer是什么以及是干什么的&#xff1f; power designer是能进行数据库设计的强大的软件&#xff0c;是一款…

nginx 代理多个服务器——多个server方式

原文链接&#xff1a;https://blog.csdn.net/wild46cat/article/details/52997005 ------------------------------------------------------------- 配置文件下载地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400nginx 代理多个服务器——多个server方…

SQL Server如何链接到 Oracle并查询其中的数据?并实现做接口

今天用Oracle的驱动教大家如何从SQL Server链接到Oracle. 1. 服务器上需要安装Oracle 64位的客户端或者服务端&#xff0c;安装过程就省略了。不会的同学可以网上搜索一下安装方法&#xff0c;很详细&#xff0c;这里不赘述。 安装完成后SQL Server的访问接口上会新增”OraOLE…

java spring bean配置文件_Spring基于xml文件配置Bean过程详解

这篇文章主要介绍了spring基于xml文件配置Bean过程详解,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下通过全类名来配置&#xff1a;class&#xff1a;bean的全类名&#xff0c;通过反射的方式在IOC容器中创建B…

win10升级后chrome碰到对话框就卡死

低版本的 chrome 会出现这样的问题 解决方法&#xff1a; 设置-------高级设置-----取消硬件加速

客户端SDK测试思路

本文来自网易云社区作者&#xff1a;万春艳是什么客户端SDK是为第三方开发者提供的软件开发工具包&#xff0c;包括SDK接口、开发文档和Demo示例等。SDK和应用之间是什么关系呢&#xff1f;以云信即时消息服务为例&#xff0c;如下图所示&#xff0c;应用客户端通过调用云信SDK…

SQL中使用DISTINCT显示多个字段的方法(不使用DISTINCT了)

原文连接&#xff1a; https://www.cnblogs.com/alanliu/archive/2008/02/25/1080626.html --------------------------------- 效果是DISTINCT CUS_NO,并且同时显示CUS_NAME.SELECTCUS_NO,MIN(CUS_NAME) ASCUS1 FROMdbo.CUS GROUPBYCUS_NO

016 pickle

英文也是泡菜的意思。 学完了&#xff0c;还是感觉这个模块是蛮不错的&#xff0c;对多数据保存到文件中&#xff0c;然后在使用的时候&#xff0c;再读取出来&#xff0c;让程序闲的更加优雅&#xff0c;简洁。 一&#xff1a;介绍 1.为什么使用 在开篇已经介绍了&#xff0c;…

用java编写日历添加窗口一角_Java 实训4 编写一个窗体程序显示日历

实训要求&#xff1a;1.使用BorderLayout 进行总体布局2.在North 位置放置包含两个按钮( 上月和下月)的Panel3.在South 位置放置一个Label 用于显示当前年份和月份4.在Center 位置放置一个显示日历的Panel5.显示日历的Panel 设置7 行7 列的GridLayout 布局&#xff0c;其中第1行…

ER图转换成关系模式集的规则

转自己博客园文章 A与B1&#xff1a;1 在A表里把B表的主键和关系的属性加入到A表中 或B表里把A表的主键和关系的属性加入到B表中 举例 男人表身份证号姓名年龄女人身份证号登记日期女人表身份证号姓名年龄 A与B1:N 在A表中加入B表的主键与关系的属性 小米公司纳税号公司全称…

python3数字类型分为_Python初学3——数字类型及操作

一、数1.1 整数类型( 十、二、八、十六进制 )python中整数类型与数学中的整数概念一致&#xff0c;有正有负&#xff0c;取值任意。整数的表示形式&#xff1a;整数类型表示形式举例十进制34,163,210二进制0b1101 或 0B1101八进制0o357 或 0O357十六进制0x45ac 或 0X45ac1.2 浮…

idea 2018.1 创建springboot开启找回Run Dashboard

原文连接&#xff1a;https://www.cnblogs.com/yangtianle/p/8818255.html ---------------------------------------------------------------------------------配置方法首先找到项目中.idea文件下的workspace.xml开打接下来找到<component name"RunDashboard"&…

微信支付-服务端-bug排查记录

微信支付服务端需要对微信官方的统一下单接口发送请求获取prepayId作为app端调用支付的凭证&#xff0c;如果返回签名错误&#xff0c;首先排查代码层面的错误。 方法&#xff1a;使用微信官方的签名算法检验。 地址&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/jsapi.…

Sqlserver备份存储过程

查了网上找不到快速备份Sqlserver存储过程的方法&#xff0c;心里想&#xff0c;如果Sqlserver不自带这个功能&#xff0c;真是太low了。步骤1&#xff1a;打开存储过程文件夹步骤2&#xff1a;按 F7 键&#xff0c;打开“对象资源管理器详细信息”窗口步骤3&#xff1a;点击“…

小哼买书JAVA编写,04_小哼买书

现在来看一个具体的例子“小哼买书”(根据全国青少年信息学奥林匹克联赛 NOIP2006 普及组第一题改编),来实践一下 章所学的三种排序算法。Paste_Image.png小哼的学校要建立一个图书角,老师派小哼去找一些同学做调查,看看同学们都喜欢读哪些书。小哼让每个同学写出一个自己最想读…

php 接口安全解决方案,php接口数据安全解决方案(一)

前言目的&#xff1a;1.实现前后端代码分离&#xff0c;分布式部署2.利用token替代session实现状态保持&#xff0c;token是有时效性的满足退出登录&#xff0c;token存入redis可以解决不同服务器之间session不同步的问题&#xff0c;满足分布式部署3.利用sign&#xff0c;前端…