一个正在执行中的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?相关推荐

  1. CSS vs. JS Animation: 哪个更快

    CSS vs. JS Animation: 哪个更快? CSS vs. JS Animation: 哪个更快? 基于JavaScript的动画竟然已经默默地比CSS的transition动画快了?而且 ...

  2. Gulp.js—比Grunt更易用的前端构建工具-前端自动化

    Gulp.js-比Grunt更易用的前端构建工具 Grunt是目前最流行的前端构建工具,对前端的效率帮助非常大,但Grunt并非完美无缺,json描述任务的方式,显得过于繁琐和不够简单,对于新手来说, ...

  3. 如何让 JS 写得更漂亮

    网上有不少关于JS编写优化建议,这里我根据自己的经验提出一些比较有用的意见. 01按强类型风格写代码 JS是弱类型的,但是写代码的时候不能太随意,写得太随意也体现了编码风格不好.下面分点说明: (1) ...

  4. 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(一)

    这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...

  5. 【深度学习】如何从结构出发更好的改进一个神经网络(二)

    [深度学习]如何从结构出发更好的改进一个神经网络(二) 文章目录 1 空洞卷积(dilated convolution) 2 PReLU 3 LeakyReLU可以解决神经元"死亡" ...

  6. 【深度学习】如何从结构出发更好的改进一个神经网络

    [深度学习]如何从结构出发更好的改进一个神经网络 文章目录 1 降采样和升采样 2 UNet++模型诞生 3 参数多了是导致UNet++比UNet好吗 4 一些思路 5 改进卷积结构5.1 转置卷积5 ...

  7. 【深度学习】如何更好的Fit一个深度神经网络框架下的模型

    [深度学习]如何更好的Fit一个深度神经网络框架下的模型 文章目录 1 随机梯度下降1.1 什么是梯度下降1.2 随机梯度算法 2 Momentum 3 自适应学习率算法3.1 AdaGrad3.2 ...

  8. html 点击按钮js自增,JS实现点击按钮自动增加一个单元格的方法

    本文实例讲述了JS实现点击按钮自动增加一个单元格的方法.分享给大家供大家参考.具体分析如下: 这是一个网页在线自助生成表格的特效代码. 核心功能代码是JS实现,点击网页中的添加按钮,网页中自动增加一个 ...

  9. 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)

    前篇 使用React.Node.js.MongoDB.Socket.IO开发一个角色投票应用的学习过程(一) 使用React.Node.js.MongoDB.Socket.IO开发一个角色投票应用的学 ...

最新文章

  1. php周计划表_PHP学习计划书
  2. 今日arXiv精选 | 23篇顶会论文:ICASSP / ICCV / CIKM / ICME / AAAI
  3. VTK:图像透明度用法实战
  4. 网工小课堂(part1)--计算机网络概论
  5. SAP CRM Opportunity items读取逻辑的优化尝试
  6. meta标签的常见用法
  7. MySQL 自带的四个数据库 介绍
  8. 下一代 IDE:Eclipse Che 究竟有什么奥秘?
  9. (转)Hibernate框架基础——映射主键属性
  10. java设计模式在线视频_Java设计模式之单例模式视频课程
  11. php高并发状态下文件的读写
  12. Entity Framework 代码先行之约定配置
  13. [译] 实例解析 ES6 Proxy 使用场景
  14. java file 其他电脑上_将MultipartFile转换为java.io.File而不复制到本地计算机
  15. win10 Python3安装pysqlcipher3的问题总结
  16. 三星 4521 linux 驱动下载,三星4521f驱动
  17. 怎么打开和修改dll文件的?如何调用和编辑?
  18. 对称加密算法 Blowfish 和 Twofish
  19. 【数学】三壶问题的一种通解
  20. “三权分立”模型之约束模型

热门文章

  1. 观光公交削弱_削弱Web开发人员和Internet的7大障碍
  2. 百钱买百鸡:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
  3. 计算机程序ui设计员工资,ui设计师工资一般多少,发展前景怎么样
  4. 这个php兼职靠谱吗?一月3000?
  5. 优秀架构师必须掌握的架构思维 - 菜鸟架构(转载)
  6. web前端开发基础知识整理以及前端视频教程
  7. A1088 Rational Arithmetic (20 分)
  8. 【OpenCV】色彩空间介绍
  9. HDU - 2072 -- 单词数【set or 字典树】
  10. @Cacheable注解介绍