(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;最近特有感触。

java bean spring_JavaBean和Spring bean傻傻分不清楚

JavaBean的定义可序列化提供无参构造提供getter/setter方法疑问在学习 Spring 的过程中发现很多 bean 对象并没有实现 Serializable 接口或提供其他可序列化的操作。这种也叫 bean&#xff1f;或者 bean 也可以不提供序列化操作&#xff1f;解决stackoverflow 一番后&#xff0…

WPF Image Source 设置相对路径图片

原文:WPF Image Source 设置相对路径图片BitmapImage bt new BitmapImage(new Uri("Images\\3_u10484.png", UriKind.Relative));this.Img1.Source bt;

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

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

python调用jar字典类型_LWPCookieJar的使用-将requests存储的cookie转换成字典

LWPCookieJar是python中管理cookie的工具&#xff0c;可以将cookie保存到文件&#xff0c;或者在文件中读取cookie数据到程序写入cookie到文件from cookielib import LWPCookieJarcj LWPCookieJar()cj.set_cookie(cookielib.Cookie(version0,names_cookie[name],values_cookie…

常用的数字正则匹配

1. 数字 ^[0-9]*$2. 1-60之间的整数 /^([1-5][0-9]$)|(^[6][0]$)|(^[1-9])$/ 3. 0-60的数字&#xff0c;可以精确到小数点后2位 /^(([0-5][0-9])|[0-9]|60|(([0-9]\.\d{1,2}|[1-5][0-9]\.\d{1,2})))$/ 4. 0-1000000的整数  /^(?!00)(?:[0-9]{1,7}|1000000)$/5. 5-10000…

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

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

sc openscmanager 失败 5 mysql_如何增加windows服务

我以前也出现过你这个问题&#xff0c;用优化大师给删了吧&#xff0c;后来也是重装的&#xff0c;其实说是重装也不是重装&#xff0c;就是修复啦&#xff0c;如果你不想这样&#xff0c;那可以试试这个&#xff0c;我没试过用在mysql上&#xff0c;但别的到是用他加载过。让程…

TemplatePart用法说明

原文:TemplatePart用法说明TemplatePart(Name"PART_Decrease", Typetypeof(RepeatButton)) 一直没明白这是干嘛用的&#xff0c;搜了一下&#xff0c;记载一下。 以Button的定义为例&#xff1a; namespace System.Windows.Controls {// Summary:// Represents a…

nginx配置多个站点共用80端口

原文链接&#xff1a;https://blog.csdn.net/zhezhebie/article/details/73459874 --------------------------------------------- 配置文件下载地址&#xff1a;https://download.csdn.net/download/zengmingen/10462400共用80端口的&#xff0c;要server_name不同。如果用域…

两点间最短路 java_AcWing 850. Dijkstra求最短路 II_Java实现含详细注释

import java.io.*;import java.util.Arrays;import java.util.Comparator;import java.util.PriorityQueue;public class Main {static final int N 150010;static int n, m; //结点数&#xff0c;边数static int[] h, e, ne, w; //邻接表适合表示稀疏图,w用来存每个边权重sta…

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

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

Tomcat 内存调大

第一种方法&#xff1a;Windows下&#xff0c;在文件/bin/catalina.bat&#xff0c;Unix下&#xff0c;在文件/bin/catalina.sh的前面&#xff0c;增加如下设置&#xff1a;JAVA_OPTS-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】需要把这个两个参数值调大。例如&#xf…

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…

nginx could not build the server_names_hash 解决方法

原文地址&#xff1a;http://www.jb51.net/article/26412.htm ------------------------------------------------------- nginx “nginx could not build the server_names_hash”解决方法 给一个服务器下增加了一些站点别名&#xff0c;差不多有20多个。 重启nginx时候&#…