javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript取消Promise操作

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

作者:东东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,简单介绍下

总结与对比

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

方案对比

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

实践建议

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

注意事项

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

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

您可能感兴趣的文章:
阅读全文