JavaScript取消Promise操作的常见实现方式

 更新时间:2025年10月22日 08:36:09   作者:东东233  
在 JavaScript 中,Promise 本身没有内置的取消机制,但我们可以通过一些模式来实现类似取消的功能,以下是几种常见的实现方式,需要的朋友可以参考下

前言

在 JavaScript 中,Promise 本身没有内置的取消机制,但我们可以通过一些模式来实现类似取消的功能。以下是几种常见的实现方式

方法一:使用 Promise.race() 模拟取消

Promise.race 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 Promise。这个返回的 promise 会随着第一个 promise 的敲定而敲定。 那么我们可以传给它两个Promise,一个正常执行,一个我们将Promise的reject方法缓存下来,只需要在我们需要取消的时候调用即可

// 封装取消函数
const cancelPromise = (promise) => {
  let cancel
  // 定义一个取消的Promise
  const rejectPromise = new Promise((_, reject) => {
    cancel = () => {
      reject({ name: 'cancel' })
    }
  })
  const resultPromise = Promise.race([promise, rejectPromise])
  return {
    cancel,
    promise: resultPromise
  }
}
const { cancel, promise } = cancelPromise(
  new Promise((resolve) => {
    // 3s之后完成
    setTimeout(() => {
      resolve({ data: [] })
    }, 3000)
  })
)
promise
  .then((res) => {
    console.log('Promise Resolve', res)
  })
  .catch((error) => {
    // 'cancel'
    console.log(error.name)
  })
setTimeout(() => {
  cancel()
}, 2000)

方法二:使用 AbortController(推荐)

AbortController 是一个构造函数,其signal我们可以传给fetch Api,然后我们只需要调用abort方法就可以取消该请求axios也支持该方法取消。

const controller = new AbortController()
fetch('http://api.com/query', { signal: controller.signal })
  .then((res) => {
    console.log(res)
  })
  .catch((error) => {
    if (error.name === 'AbortError') {
      console.log('Promise 已取消')
    }
  })
// 超时取消
setTimeout(() => {
  controller.abort()
}, 2000)

被取消的请求会被浏览器标记为canceled

方法三:使用 Bluebird 库

Bluebird 是一个完善的Promise库,其完全遵循Promises/A+标准,所以我们可以像日常使用Promise一样使用他,而且它有许多超越原生Promise的功能、比如支持 Promise 取消、进度追踪、超时控制、更强大的错误处理机制(如 OperationalError)等。我们使用时候只需要安装后直接引入即可

yarn add bluebird
import Promise from 'bluebird'
...
// 打开取消功能
Promise.config({ cancellation: true })
const testPromise  = new Promise((resolve, reject, onCancel) => {
  setTimeout(() => {
    resolve('成功')
  }, 3000)
  onCancel(function () {
    console.log('promise 已被取消')
  })
})
  .then((res) => {
    console.log(res)
  }).finally(() => {
    // 判断Promise是否取消
    if(testPromise.isCancelled()) {
      console.log('promise 已被取消')
    }
  })
setTimeout(() => {
  // 取消Promise
  testPromise.cancel()
}, 1000)

可以看到正常使用和原生Promise并无区别,但是新增了onCancel、cancel、config等Api,简单介绍下

  • cancel:用于取消当前Promise
  • onCancel:Promise取消后会调用传入该方法的回调
  • isCancelled:判断Promise是否取消
  • config:配置项,因为取消Promise在当前版本中是默认关闭、传入cancellation: true打开取消功能

总结与对比

在前端开发中,取消 Promise 操作是处理异步流程控制的重要能力。以下是各方案的对比:

方案对比

方案优点缺点适用场景
Promise.race()纯 JavaScript 实现,无需额外库只是"模拟"取消,实际异步操作仍在执行简单的取消需求,兼容性要求高
AbortController原生支持,与 fetch API 深度集成较新的 API,需要 polyfill网络请求取消,现代浏览器项目
Bluebird功能丰富,API 完善需要引入第三方库,增加包体积需要高级 Promise 功能的复杂应用

实践建议

  1. 现代项目首选 AbortController - 随着原生支持的普及,这是最标准和推荐的方式
  2. 简单场景用 Promise.race() - 对于简单的取消需求,这种方式足够且轻量
  3. 复杂异步流程考虑 Bluebird - 如果需要进度追踪、超时控制等高级功能

注意事项

  • 取消 Promise 并不意味着底层操作真的停止了(如定时器)
  • 要及时清理资源,避免内存泄漏
  • 在 React/Vue 等框架中,组件卸载时务必取消未完成的异步操作

选择合适的方法取决于具体需求、浏览器兼容性要求和项目架构。

以上就是JavaScript取消Promise操作的常见实现方式的详细内容,更多关于JavaScript取消Promise操作的资料请关注脚本之家其它相关文章!

相关文章

  • 微信小程序非swiper组件实现的自定义伪3D轮播图效果示例

    微信小程序非swiper组件实现的自定义伪3D轮播图效果示例

    这篇文章主要介绍了微信小程序非swiper组件实现的自定义伪3D轮播图效果,涉及微信小程序事件响应及元素属性动态操作实现轮播图效果相关技巧与注意事项,需要的朋友可以参考下
    2018-12-12
  • 使用JavaScript实现网页版Pongo设计思路及源代码分享

    使用JavaScript实现网页版Pongo设计思路及源代码分享

    Pongo是款很好玩的手欠类游戏,由于在玩的过程中发现了一些BUG,所以就打算自己也弄个,经过一番思索,就有了本文,主要说说实现这款游戏的设计思路以及分享源码给大家
    2014-06-06
  • js拖动div 当鼠标移动时整个div也相应的移动

    js拖动div 当鼠标移动时整个div也相应的移动

    要拖动的div为最外层的div,这段代码对显示对话框的头部绑定鼠标监听事件,当鼠标移动时,整个div也相应的移动,具体的实现如下,感兴趣的朋友可以参考下
    2013-11-11
  • js实现图片跟随鼠标移动效果

    js实现图片跟随鼠标移动效果

    这篇文章主要为大家详细介绍了js实现图片跟随鼠标移动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-10-10
  • 浅谈js闭包理解

    浅谈js闭包理解

    这篇文章主要介绍了对js闭包理解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • js实现旋转的星空效果

    js实现旋转的星空效果

    这篇文章主要为大家详细介绍了js实现旋转的星空效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • 面向JavaScript入门初学者的二叉搜索树算法教程

    面向JavaScript入门初学者的二叉搜索树算法教程

    二叉搜索树则是二叉树的一种,但它只允许你在左侧节点储存比父节点小的值,右侧只允许储存比父节点大的值,这篇文章主要给大家介绍了关于JavaScript二叉搜索树算法的相关资料,需要的朋友可以参考下
    2021-09-09
  • JS获取当前时间实例代码(年月日时分秒)

    JS获取当前时间实例代码(年月日时分秒)

    在javascript中,可以使用Date对象中的Date()方法来获取当前时间,下面这篇文章主要给大家介绍了关于JS获取当前时间(年月日时分秒)的相关资料,需要的朋友可以参考下
    2022-09-09
  • document.compatMode的CSS1compat使用介绍

    document.compatMode的CSS1compat使用介绍

    这篇文章主要介绍了document.compatMode的CSS1compat使用,需要的朋友可以参考下
    2014-04-04
  • 一文详解如何在浏览器中使用JavaScript

    一文详解如何在浏览器中使用JavaScript

    这篇文章主要介绍了在浏览器中使用JavaScript的步骤,包括启用JavaScript、编写和运行JavaScript代码的方法,以及一些注意事项,需要的朋友可以参考下
    2025-03-03

最新评论