记录--前端中 JS 发起的请求可以暂停吗
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
在前端中,JavaScript(JS)可以使用XMLHttpRequest对象或fetch API来发起网络请求。然而,JavaScript本身并没有提供直接的方法来暂停请求的执行。一旦请求被发送,它会继续执行并等待响应。
尽管如此,你可以通过一些技巧或库来模拟请求的暂停和继续执行。下面是一种常见的方法:
1. 使用XMLHttpRequest对象
你可以在发送请求前创建一个XMLHttpRequest对象,并将其保存在变量中。然后,在需要暂停请求时,调用该对象的abort()方法来中止请求。当需要继续执行请求时,可以重新创建一个新的XMLHttpRequest对象并发起请求。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/api', true);
xhr.send(); // 暂停请求
xhr.abort(); // 继续请求
xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/api', true);
xhr.send();
2. 使用fetch API和AbortController
fetch API与AbortController一起使用可以更方便地控制请求的暂停和继续执行。AbortController提供了一个abort()方法,可以用于中止fetch请求。
var controller = new AbortController();
fetch('https://example.com/api', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// 暂停请求
controller.abort();
// 继续请求
controller = new AbortController();
fetch('https://example.com/api', { signal: controller.signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
请注意,这些方法实际上是通过中止请求并重新发起新的请求来模拟暂停和继续执行的效果,并不能真正暂停正在进行的请求。
3. 曲线救国
模拟一个假暂停的功能,在前端的业务场景上,需要对这些数据进行处理之后渲染在界面上,如果我们能在请求发起之前增加一个控制器,在请求回来时,如果控制器为暂停状态则不处理数据,等待控制器恢复后再进行处理,也可以达到暂停的效果。
// 创建一个暂停控制器 Promise
function createPauseControllerPromise() {
const result = {
isPause: false, // 标记控制器是否处于暂停状态
resolveWhenResume: false, // 表示在恢复时是否解析 Promise
resolve(value) {}, // 解析 Promise 的占位函数
pause() { // 暂停控制器的函数
this.isPause = true;
},
resume() { // 恢复控制器的函数
if (!this.isPause) return;
this.isPause = false;
if (this.resolveWhenResume) {
this.resolve();
}
},
promise: Promise.resolve(), // 初始为已解决状态的 Promise
}; const promise = new Promise((res) => {
result.resolve = res; // 将解析函数与 Promise 关联
});
result.promise = promise; // 更新控制器中的 Promise 对象 return result; // 返回控制器对象
} function requestWithPauseControl(request) {
const controller = createPauseControllerPromise(); // 创建暂停控制器对象 const controlRequest = request() // 执行请求函数
.then((data) => { // 请求成功回调
if (!controller.isPause) controller.resolve(); // 如果控制器未暂停,则解析 Promise
return data; // 返回请求结果
})
.finally(() => {
controller.resolveWhenResume = true; // 标记在恢复时解析 Promise
}); const result = Promise.all([controlRequest, controller.promise]).then(
(data) => {
controller.resolve(); // 解析控制器的 Promise
return data[0]; // 返回请求处理结果
}
); result.pause = controller.pause.bind(controller); // 将暂停函数绑定到结果 Promise 对象
result.resume = controller.resume.bind(controller); // 将恢复函数绑定到结果 Promise 对象 return result; // 返回添加了暂停控制功能的结果 Promise 对象
}
为什么需要创建两个promise
在requestWithPauseControl函数中,需要等待两个Promise对象解析:一个是请求处理的Promise,另一个是控制器的Promise。通过使用Promise.all方法,可以将这两个Promise对象组合成一个新的Promise,该新的Promise会在两个原始Promise都解析后才会解析。这样做的目的是确保在处理请求结果之前,暂停控制器的resolve方法被调用,以便在恢复时解析Promise。
因此,将请求处理的Promise和控制器的Promise放入一个Promise数组,并使用Promise.all等待它们都解析完成,可以确保在两个Promise都解析后再进行下一步操作,以实现预期的功能。
使用
const result = requestWithPauseControl(/*request fn*/).then((data) => {
console.log(data)
})
if (Math.random() > 0.5) { result.pause() }
setTimeout(() => {
result.resume()
}, 4000)
本文转载于:
https://juejin.cn/post/7310786521082560562
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--前端中 JS 发起的请求可以暂停吗的更多相关文章
- 【问题记录】Java服务发起HTTPS请求报错:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException
问题报错 今天上线了我开发的一个OAuth2单点登录客户端的实现,在测试系统验证没问题,到生产环境由于单点登录服务端HTTPS协议,报错如下: I/O error on POST request fo ...
- openresty开发系列29--openresty中发起http请求
openresty开发系列29--openresty中发起http请求 有些场景是需要nginx在进行请求转发 用户浏览器请求url访问到nginx服务器,但此请求业务需要再次请求其他业务:如用户请求 ...
- javaWeb - 2 — ajax、json — 最后附:后台获取前端中的input type = "file"中的信息 — 更新完毕
1.ajax是什么? 面向百度百科一下就知道了,这里就简单提炼一下 Ajax即Asynchronous Javascript And XML(异步JavaScript和XML).当然其实我们学的应该叫 ...
- iOS swift HandyJSON组合Alamofire发起网络请求并转换成模型
在swift开发中,发起网络请求大部分开发者应该都是使用Alamofire发起的网络请求,至于请求完成后JSON解析这一块有很多解决方案,我们今天这里使用HandyJSON来解析请求返回的数据并转化成 ...
- 过滤器会拦截 前端页面加载 js文件的请求
学艺不精啊.....之前就总结过博客: JAVA中解决Filter过滤掉css,js,图片文件等问题 结果现在又犯了老错误~ 情况如下: index.jsp 页面的验证码输入栏绑定了异步验证(jQur ...
- NET MVC全局异常处理(一) 【转载】网站遭遇DDoS攻击怎么办 使用 HttpRequester 更方便的发起 HTTP 请求 C#文件流。 Url的Base64编码以及解码 C#计算字符串长度,汉字算两个字符 2019周笔记(2.18-2.23) Mysql语句中当前时间不能直接使用C#中的Date.Now传输 Mysql中Count函数的正确使用
NET MVC全局异常处理(一) 目录 .NET MVC全局异常处理 IIS配置 静态错误页配置 .NET错误页配置 程序设置 全局异常配置 .NET MVC全局异常处理 一直知道有.NET有相关 ...
- 前端发起resultUrl请求,服务端收到后做逆向处理,校验sign后,执行originUrl逻辑
originUrl=http://test.com:8080/user/alipay_phone?uid=123&amount=21.3第0步:前后端约定32位密钥KEY第一步:对参数按照ke ...
- Node.js模拟发起http请求从异步转同步的5种方法
使用Node.js模拟发起http请求很常用的,但是由于Node模块(原生和第三方库)提供里面的方法都是异步,对于很多场景下应用很麻烦,不如同步来的方便.下面总结了几个常见的库API从异步转同步的几种 ...
- 【js 正则表达式】记录所有在js中使用正则表达式的情况
说实话,对正则表达式有些许的畏惧感,之前的每次只要碰到需要正则表达式去匹配的情况,都会刻意的躲过或者直接从度娘处获取. 此时此刻,感觉到了某一个特定的点去触及她.但笔者对于正则表达式使用上的理解是这样 ...
- java中两种发起POST请求,并接收返回的响应内容的方式 (转)
http://xyz168000.blog.163.com/blog/static/21032308201162293625569/ 2.利用java自带的java.net.*包下提供的工具类 代码如 ...
随机推荐
- NC201985 立方数
题目链接 题目 题目描述 对于给定的正整数 N,求最大的正整数 A,使得存在正整数 B,满足 \(A^3B=N\) 输入包含 T 组数据,1≤T≤10,000:\(1≤N≤10^{18}\) 输入描述 ...
- 2023牛客暑期多校训练营6 ABCEG
比赛链接 A 题解 方法一 知识点:并查集,树形dp,背包dp. 因为需要路径中的最大值,因此考虑按边权从小到大加入图中,保证通过这条边产生贡献的点对已经全部出现. 在加边的同时进行树上背包,答案存在 ...
- SSL证书类型价格和购买
SSL证书 SSL和HTTPS的工作机制就不多说了, 密钥交换加通道依然是非常靠谱的安全访问方式, 除非你的浏览器连证书和DNS都被劫持, 否则中间节点要解密/篡改HTTPS访问的可能性微乎其微. 现 ...
- 【OpenGL ES】EGL+FBO离屏渲染
1 前言 FBO离屏渲染 中使用 GLSurfaceView 来驱动 Renderer 渲染图片,为了隐藏 GLSurfaceView,将其设置为透明的,并且宽高都设置为1.本文将使用 EGL 代 ...
- 搭建docker swarm集群
环境介绍 管理节点 swarm01 192.168.5.140 工作节点 swarm02 192.168.5.141 管理节点执行 docker swarm init --advertise ...
- 一秒出图?SDXL-Turbo实时AI绘画整合包下载
SDXL Turbo是一种快速生成的AI构图模型,它基于一种称为对抗性扩散蒸馏的新训练方法,该方法允许在1到4个步骤中以高图像质量对大规模基础图像扩散模型进行采样,并将其与对抗性损失相结合,以确保即使 ...
- 一个有意思的问题:Kafka的消费Offset会溢出吗
最近在项目上接入公司APP产品的用户点击日志数据时,发现消费者组的Offset值非常大,才一天的时间,已提交的Offset值就有千亿级别了. 于是不禁想了一个问题:假设一个Topic就只有一个Part ...
- 2019年在浏览器用原生js写WebGL,绘制图形;
因为JavaScript高级程序设计(第三版)中的运行书上15.3WebGL部分的代码时在chrome和firefox浏览器下报错,在后面我网上初步找了一圈,好像没人做出真正可以用的代码;所以我就自己 ...
- 2021-07-30 JavaScript中常用数据的判断
为什么要判断一个变量的常用数据? 实际业务场景里,一个变量的数据是否合法或符合预期,会影响到项目中用到的UI组件库特定组件的运行.比如element-ui中的el-select组件,单选时绑定的数据不 ...
- 公司服务器建站笔记(三):腾讯云服务器CentOS8.2安装界面环境,使用vnc远程登陆并搭建轻量级Qt服务器
前言 有些小项目可能只有几个点,几十个点,几百个点,这个时候使用qt的tcp服务器或者mqtt或者websocket等相关服务就可以满足,腾讯云CentOs8.2服务器安装的是没有界面的版本,本篇 ...
