【JS】1126- 如何更好的取消一个promise?
一个正在执行中的promise怎样被取消?
其实就像一个执行中的ajax要被取消一样,ajax有abort()进行取消,而且fetch api 也有了相关的规范-【AbortController】。
fetch 怎样取消?
先来看下如何取消一个fetch请求
const url = "https://bigerfe.com/api/xxxx"
let controller;
let signal;function requestA(){if (controller !== undefined) {controller.abort(); //终止请求}if ("AbortController" in window) {controller = new AbortController;signal = controller.signal;}fetch(url, {signal}).then((response) => {//do xxxupdateAutocomplete()}).catch((error) => {//do xxxhandleError(error);})});
}
怎样实现实现promise的取消?
方案1 - 借助reject 方法
我们都知道一个promise对象状态的改变是通过resolve和reject来执行的。那是不是可以借助reject方法来模拟呢?
上代码
//返回一个promise和abort方法
function getPromise() {let _res, _rej;const promise = new Promise((resolve, reject) => {_res = resolve;_rej = reject;setTimeout(() => {resolve('123')}, 5000);});return {promise,abort: () => {_rej({name: "abort",message: "the promise is aborted",aborted: true,});}};
}const { promise, abort } = getPromise();
promise.then(console.log).catch(e => {console.log(e);
});abort();
上面的方法可以正常执行,但是不够通用,可以将Promise构造函数内的逻辑提取出来,作为一个回调传进去。
改造一下
function getPromise(cb) {let _res, _rej;const promise = new Promise((res, rej) => {_res = res;_rej = rej;cb && cb(res,rej);});return {promise,abort: () => {_rej({name: "abort",message: "the promise is aborted",aborted: true,});}};
}//主逻辑提取出来
function runCb(resolve,reject){setTimeout(()=>{resolve('1111')},3000)
}const { promise, abort } = getPromise(runCb);
promise.then(console.log).catch(e => {console.log(e);
});
方案2 - 借助 Promise.race() 方法
相信大家都知道race方法的作用,这里还是简单介绍下。
当有若干个promise, p1, p2, p3…在调用, let p = Promise.race([p1, p2, p3,…])的时候,返回的p也是一个promise。那么p什么时候会被resolve或者被reject呢?
看race我们知道它是竞速或赛跑的意思,所以p1, p2, p3 … 最先一个被resolve或者被reject的结果就是p的resolve或者reject的结果。所以后续的promise的resolve和reject都不会再被执行了。
代码很简单,其实够短小精悍。
//传入一个正在执行的promise
function getPromiseWithAbort(p){let obj = {};//内部定一个新的promise,用来终止执行let p1 = new Promise(function(resolve, reject){obj.abort = reject;});obj.promise = Promise.race([p, p1]);return obj;
}
调用
var promise = new Promise((resolve)=>{setTimeout(()=>{resolve('123')},3000)
})var obj = getPromiseWithAbort(promise)obj.promise.then(res=>{console.log(res)})//如果要取消
obj.abort('取消执行')
借助race方法明显的更简洁,更易用。
最后
其实取消promise执行和取消请求是一样的,并不是真的终止了代码的执行,而是对结果不再处理。另外fetch api虽然增加了新的标准实现,但仍然存在兼容问题,而且只能在浏览器中使用。那么非浏览器的环境中呢?比如RN?所以如果想要达到一种通用的方式,那么本文的取消promise的方式应该是个不错的方式。
目前知名的axios库也有abort能力,回头看下它的实现方式,也欢迎小伙伴们留言讨论。
---end,希望对你有用。
1. JavaScript 重温系列(22篇全)
2. ECMAScript 重温系列(10篇全)
3. JavaScript设计模式 重温系列(9篇全)
4. 正则 / 框架 / 算法等 重温系列(16篇全)
5. Webpack4 入门(上)|| Webpack4 入门(下)
6. MobX 入门(上) || MobX 入门(下)
7. 120+篇原创系列汇总
回复“加群”与大佬们一起交流学习~
点击“阅读原文”查看 120+ 篇原创文章
【JS】1126- 如何更好的取消一个promise?相关推荐
- CSS vs. JS Animation: 哪个更快
CSS vs. JS Animation: 哪个更快? CSS vs. JS Animation: 哪个更快? 基于JavaScript的动画竟然已经默默地比CSS的transition动画快了?而且 ...
- Gulp.js—比Grunt更易用的前端构建工具-前端自动化
Gulp.js-比Grunt更易用的前端构建工具 Grunt是目前最流行的前端构建工具,对前端的效率帮助非常大,但Grunt并非完美无缺,json描述任务的方式,显得过于繁琐和不够简单,对于新手来说, ...
- 如何让 JS 写得更漂亮
网上有不少关于JS编写优化建议,这里我根据自己的经验提出一些比较有用的意见. 01按强类型风格写代码 JS是弱类型的,但是写代码的时候不能太随意,写得太随意也体现了编码风格不好.下面分点说明: (1) ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(一)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...
- 【深度学习】如何从结构出发更好的改进一个神经网络(二)
[深度学习]如何从结构出发更好的改进一个神经网络(二) 文章目录 1 空洞卷积(dilated convolution) 2 PReLU 3 LeakyReLU可以解决神经元"死亡" ...
- 【深度学习】如何从结构出发更好的改进一个神经网络
[深度学习]如何从结构出发更好的改进一个神经网络 文章目录 1 降采样和升采样 2 UNet++模型诞生 3 参数多了是导致UNet++比UNet好吗 4 一些思路 5 改进卷积结构5.1 转置卷积5 ...
- 【深度学习】如何更好的Fit一个深度神经网络框架下的模型
[深度学习]如何更好的Fit一个深度神经网络框架下的模型 文章目录 1 随机梯度下降1.1 什么是梯度下降1.2 随机梯度算法 2 Momentum 3 自适应学习率算法3.1 AdaGrad3.2 ...
- html 点击按钮js自增,JS实现点击按钮自动增加一个单元格的方法
本文实例讲述了JS实现点击按钮自动增加一个单元格的方法.分享给大家供大家参考.具体分析如下: 这是一个网页在线自助生成表格的特效代码. 核心功能代码是JS实现,点击网页中的添加按钮,网页中自动增加一个 ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
前篇 使用React.Node.js.MongoDB.Socket.IO开发一个角色投票应用的学习过程(一) 使用React.Node.js.MongoDB.Socket.IO开发一个角色投票应用的学 ...
最新文章
- php周计划表_PHP学习计划书
- 今日arXiv精选 | 23篇顶会论文:ICASSP / ICCV / CIKM / ICME / AAAI
- VTK:图像透明度用法实战
- 网工小课堂(part1)--计算机网络概论
- SAP CRM Opportunity items读取逻辑的优化尝试
- meta标签的常见用法
- MySQL 自带的四个数据库 介绍
- 下一代 IDE:Eclipse Che 究竟有什么奥秘?
- (转)Hibernate框架基础——映射主键属性
- java设计模式在线视频_Java设计模式之单例模式视频课程
- php高并发状态下文件的读写
- Entity Framework 代码先行之约定配置
- [译] 实例解析 ES6 Proxy 使用场景
- java file 其他电脑上_将MultipartFile转换为java.io.File而不复制到本地计算机
- win10 Python3安装pysqlcipher3的问题总结
- 三星 4521 linux 驱动下载,三星4521f驱动
- 怎么打开和修改dll文件的?如何调用和编辑?
- 对称加密算法 Blowfish 和 Twofish
- 【数学】三壶问题的一种通解
- “三权分立”模型之约束模型