手写axios源码系列五:CancelToken取消请求类封装

news2024/12/25 12:31:46

在这里插入图片描述

文章目录

  • 一、使用 CancelToken 取消请求
    • 1、创建 CancelToken.js 文件
    • 2、发送请求时订阅 onCanceled 方法
  • 二、使用 AbortController 取消请求
  • 三、使用 json-server 测试"取消请求"功能代码
    • 1、全局安装 json-server
    • 2、创建 db.json 文件并监听文件
    • 3、创建 index.html 测试代码

在第一篇章节 手写axios源码系列一:axios核心知识点 中,我们知道取消请求有两种配置方式:

  1. config.cancelToken
  2. config.signal

两种方式都可以取消请求,接下来我们探究一下两种取消请求的方式有何不同。

一、使用 CancelToken 取消请求

config.cancelToken 取消请求的方式是封装 CancelToken 类,使用发布/订阅模式对发送的请求进行了订阅 onCanceled 方法,然后在需要时执行 onCanceled 方法取消请求。

1、创建 CancelToken.js 文件

export default class CancelToken {
	constructor(executor){
		let resolvePromise;
		// 给实例对象添加 promise属性
		this.promise = new Promise(function promiseExecutor(resolve){
			// 暴露 resolve方法,可以在外部执行 resolvePromise方法改变当前 pending状态的 promise为 fulfilled
			resolvePromise = resolve;
		})
		// 调用执行器函数,传入一个函数
		executor(function c(){
			resolvePromise()
		})
		// 当 this.promise状态变更时执行取消请求订阅事件
		this.promise.then(() => {
			const i = this._listeners.length;
			// 循环数组倒序执行
			while(i-- > 0){
				this._listeners[i]();  // 执行取消请求 onCanceled方法
			}
			// 置空 _listeners
			this._listeners = null;
		})
	}
	// 订阅事件方法 subscribe
	subscribe(listener){
		if (this._listeners){
			// 向 _listeners中添加监听函数
			this._listeners.push(listenner)
		} else {
			// 创建 this._listeners容器
			this._listeners = [listener]
		}
	}
	// 静态方法 source,其实是一个工厂函数
	static source(){
		let cancel;
		// token为 CancelToken的实例对象,带有 subscribe订阅方法
		const token = new CancelToken(function executor(c){
			cancel = c;
		});
		return { token, cancel }
	}
}

2、发送请求时订阅 onCanceled 方法

什么时候订阅取消请求 onCanceled 方法呢?
发送请求应该与取消请求是相耦合的,所以应该在发送请求的时候订阅取消当前请求的方法 onCanceled 。

发送请求的代码写在 xhr.js下:

export default function xhrAdapter(config) {
	// 返回一个 promise对象
	return new Promise((resolve, reject) => {
		// 其他代码
		// ...
		// 发送请求
		request.send(config.data || null);
		// 订阅取消请求,根据 config中是否配置了 cancelToken字段来判断是否需要取消请求
		if (config.cancelToken) {
			const onCanceled = () => {
				request.abort();  // 中止请求
			}
			// 订阅取消请求 onCanceled方法
			config.cancelToken.subscribe(onCanceled);
		}
	})
}

二、使用 AbortController 取消请求

使用 AbortController 的方式取消请求代码很简单,根据 config 对象中是否配有 signal 字段来判断,如果有则取消请求,没有则不做任何操作。

修改 xhr.js 文件代码:

export default function xhrAdapter(config) {
	// 返回一个 promise对象
	return new Promise((resolve, reject) => {
		// 其他代码
		...
		// 发送请求
		request.send(config.data || null);
		// 订阅取消请求,根据 config中是否配置了 cancelToken字段或者 signal字段来判断是否需要取消请求
		if (config.cancelToken || config.signal) {
			const onCanceled = () => {
				request.abort();  // 中止请求
			}
			// 订阅取消请求 onCanceled方法
			config.cancelToken && config.cancelToken.subscribe(onCanceled);
			// signal字段判断
			if (config.signal){
				/**
				 * const controller = new AbortController()
				 * signal是 controller.signal对象,带有三个属性
				 * signal:{ 
				 * 		aborted: false,  	通信请求是否被终止(true)或未终止(false),只读属性。
				 * 		onabort: null,   	监听事件。
				 * 		reason: undefined	取消请求原因。
				 * } 
				 */
				// aborted 字段为 true时直接取消请求,否则添加 abort监听取消事件
				config.signal.aborted ? onCanceled() : config.signal.addEventListener("abort", onCanceled);
			}
		}
	})
}

三、使用 json-server 测试"取消请求"功能代码

json-server 是一个可以在前端本地运行,存储 json 数据格式的快速启用的服务器。可以说它就是一个 mock 数据服务,可以模仿RESTful API。

1、全局安装 json-server

npm i -g json-server

2、创建 db.json 文件并监听文件

{
  "posts": [
    {
      "id": 1,
      "title": "json-server",
      "author": "typicode"
    },
    {
      "id": 2,
      "title": "json-server2",
      "author": "typicode2"
    }
  ]
}

监听指令:json-server --watch db.json

因为我们这里要测试取消请求,所以给请求添加个延迟时间,容易操作。

执行指令:json-server --watch -d 2000 db.json,请求会在延迟2s后返回响应数据。

3、创建 index.html 测试代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>axios源码解析</title>
</head>
<body>
  <button id="request">请求接口</button>
  <button id="cancel">取消请求</button>

  <script type="module">
    import axios from "./axios.js";
    const requestBtn = document.querySelector("#request");
    const cancelBtn = document.querySelector("#cancel");
    let source = null;
    // let controller = null

    requestBtn.addEventListener("click", function () {
      // controller = new AbortController();
      source = axios.CancelToken.source();
      // 发送请求
      axios({
        method: "get",
        url: "http://localhost:3000/posts",
        // signal: controller.signal,
        cancelToken: source.token
      }).then(response => {
        console.log(response);
      })
    });
    // 取消请求
    cancelBtn.addEventListener("click", function () {
   	  // controller.abort();
      source.cancel();
    });
  </script>
</body>
</html>

在这里插入图片描述

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

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

相关文章

真心不负,合作长久| 凌恩客户亲述“我和凌恩的故事”

我和凌恩的故事 —Biozeron stories— 分享嘉宾介绍 中国热带农业科学院 环境与植物保护研究所 岳政府 助理研究员&#xff0c;2022年加入环植所农业资源环境团队&#xff0c;主要从事抗生素抗性基因的风险评价、病毒介导抗性基因传播的微生物学机制等研究&#xff0c…

K_A35_002 基于STM32等单片机采集TTP223按键模块状态 串口与OLED0.96双显示

K_A35_002 基于STM32等单片机采集TTP223按键模块状态 串口与OLED0.96双显示 所有资源导航一、资源说明二、基本参数参数引脚说明 三、驱动说明模块工作原理:对应程序: 四、部分代码说明1、接线引脚定义1.1、STC89C52RCTTP223按键模块1.2、STM32F103C8T6TTP223按键模块 五、基础…

两个数组的交集

给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 思路&#xff1a; 由于这道题目&#xff0c;输出结果中的每个元素一定是唯一的&#xff0c;也就是说输出的结果的去重的&#xff0c; 同时可…

栈及其应用

栈 在使用一个东西之前&#xff0c;得清楚它是什么&#xff0c;才能知道它的用途以及该如何使用。 栈的简介 栈&#xff08;stack&#xff09;又名堆栈&#xff0c;它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶(top)&#xff0c;相…

Direct3D 12——计算着色器——线程标识的系统值

1.系统会为每个线程组都分配一个ID,这个ID称为线程组ID ( group ID),其系统值的语义为 SV_GroupID。如果Gx x Gy x Gz&#xff1a;为所分派线程组的个数&#xff0c;则组ID的范围为(0, 0, 0)至(Gx-1,Gy-1,Gz-1)。 2.在线程组中&#xff0c;每个线程都被指定了一个组内的唯一 I…

企企通受邀出席嘉兴产业数字化峰会,助力嘉兴“智”造业发展

近日&#xff0c;2023年嘉兴产业数字化峰会在浙江嘉兴圆满举办&#xff0c;企企通作为采购供应链厂商受邀出席&#xff0c;并与众多信息化领域的专家一起分享心得、总结得失、展望未来&#xff0c;为嘉兴市企业的产业数字化发展探索合适的路径与方向。 01、数字蓄能&#xff0c…

【 Linux命令行与Shell脚本编程】第四章 进程管理 ,磁盘统计信息,挂载新磁盘,数据排序,数据归档

Linux命令行与Shell脚本编程 第四章 更多命令 进程管理 磁盘统计信息 挂载新磁盘 数据排序 数据归档 文章目录 Linux命令行与Shell脚本编程四,更多命令4.1,监测程序4.1.1,ps 探查进程4.1.2,top 实时监测进程4.1.3,kill pkill 结束进程1,kill 命令2,pkill 命令 4.2,检测磁盘空间…

Django+模板引擎+Bootstrap +sqlite3 个人博客管理系统

目录 1.准备工作1.1 参考博客1.2 项目环境与结构预览1.3 项目功能点与预览效果 1.准备工作 1.1 参考博客 1、【python】怎么导出python虚拟环境库以及导入 2、Django之分页功能 主要参考了这篇博客。 1.2 项目环境与结构预览 创建虚拟环境&#xff0c;基于Django版本1.11.2…

25-Maven

目录 1.什么是Maven&#xff1f; PS&#xff1a;关于 jar 包 2.配置并使用Maven 2.1.Maven依赖管理流程 2.2.Maven国内源配置 ①确认右边的两个勾已经都选中。 ②查看自己电脑上settings.xml文件是否存在&#xff0c;进而进行相关配置 ③配置所有新项目配置文件 PS&am…

剑指offer练习日志02:基于矩阵乘法求斐波那契数列通项

目录 一.矩阵乘法与斐波那契数列 1.利用数列的项构造二阶方阵 2.引入矩阵乘法 二.算法实现 1.MatrixFib对象成员变量 2.MatrixFib对象的构造函数 3. MatrixFib对象的成员算法接口 4.对象测试 一.矩阵乘法与斐波那契数列 1.利用数列的项构造二阶方阵 &#x1f604;现定…

【项目实战-CRM】(二:物理模型设计 搭建CRM项目环境)

文章目录 1.物理模型设计2.搭建开发环境2.1 创建crm项目2.2 创建模块2.3 添加jar包2.4 相关配置2.4.1 MyBatis 配置2.4.2 配置数据连接和事务2.4.3 SpringMVC配置文件2.4.4 Spring总配置文件2.4.5 web.xml2.4.6 设置maven对配置文件的编译选项 2.5 添加静态页面资源2.6 将项目部…

在VMmare上安装Windows 2003

今天和大家介绍一下如何使用VMmare安装一个Windows 2003 Enterprise Edition操作系统 首先小陈先下载了一个VMmare 10虚拟软件&#xff0c;将其安装在自己的电脑上。 一、新建虚拟机 然后打开VMmare软件&#xff0c;在窗口的菜单栏里点击“文件”-->“新建虚拟机” 这边让…

c++验证用户输入合法性的示例代码

c验证用户输入合法性的示例代码 本文介绍c验证用户输入合法性&#xff0c;用于检测限定用户输入值。包括&#xff1a;1、限定用户输入为整数&#xff08;正负整数&#xff09;&#xff1b;2、限定用户输入为正整数&#xff1b;3、限定用户输入为正数&#xff08;可以含有小数&…

AI算力碎片化:矩阵乘法的启示

尽管AI的发展取得了巨大进步&#xff0c;但编译器LLVM之父Chris Lattner认为&#xff0c;AI技术应用并不深入&#xff0c;远远没有发挥出已有机器学习研究的所有潜力。而AI系统和工具的单一化和碎片化正是造成这一问题的根源。 为了让AI发挥其真正的潜力&#xff0c;计算碎片化…

Oracle中实现恢复删除的表或表数据内容

一、需求说明 在我们进行项目开发或运维过程中,由于操作不当,引起的误删Oracle数据库表或指定表的数据内容,导致程序出现故障;而我们又没有对数据库进行备份,此时,如果不能及时恢复数据库内容将会导致严重的事故。我们需要一种能够补救的方法来挽回损失,恢复被误删的表或…

WEB攻防-弱口令暴力破解(包含工具、字典下载地址)

目录 一、弱口令概述 二、Web类-加密&验证码后台猜解 三、服务类-SSH&RDP远程终端猜解 四、应用类-ZIP&Word文件压缩包猜解 一、弱口令概述 弱口令(weak password) 没有严格和准确的定义&#xff0c;通常认为容易被别人&#xff08;他们有可能 对你很了解&#…

025:Mapbox GL加载栅格高程模型raster-dem文件

第025个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载image图像文件。栅格 DEM 源。 仅支持 Mapbox Terrain-DEM,您可以将 Terrain-DEM 用于各种视觉和分析应用程序,从样式化地形坡度和山体阴影到为视频游戏生成 3D 地形网格。 直接复制下面的 vue+mapbo…

记录一个dpdk 19.11 hello world 跑不起来问题(编译和权限)

下载dpdk 源码后: git clone gitgithub.com:DPDK/dpdk.git 切到 19.11 git checkout v19.11 用usertool下的dpdk_setup.sh 选择 [38] x86_64-native-linuxapp-gcc 进行编译: 结果者是build 不过: Build kernel/linux/igb_uio Build kernel/linux/kni CC [M] /home/t…

Linux查看GPU信息和使用情况

1.Linux查看显卡信息 lspci | grep -i vga 2.使用nvidia GPU lspci | grep -i nvidia 个人感觉看不出什么信息&#xff0c;除了显存大小&#xff0c;另外就是可以通过加入前面的显卡编号&#xff0c;显示更加详细的信息。 lspci -v -s 00:0f.0 3.Linux查看Nvidia显卡信息及使…

软件测试之学习测试用例的设计(等价类法、边界值法、错误猜测法、场景法、因果图法、正交法)

文章目录 1. 测试用例的概念2. 为什么在测试前要设计测试用例3. 基于需求进行测试用例的设计1&#xff09;功能性需求测试2&#xff09;非功能性需求测试 4. 具体的测试用例设计方法1&#xff09;等价类2&#xff09;边界值3&#xff09;错误猜测法4&#xff09;场景法5&#x…