中断 Promise 的方法

实现 Promise 调用链中断和超时控制

问题

Promise 一旦创建就无法取消,但在实际开发中需要实现两种场景:中断调用链(阻止后续 then/catch 执行)和中断 Promise(如超时控制)。

解答

中断调用链

在 then 中返回一个永远处于 pending 状态的 Promise,可以阻止后续链式调用执行:

Promise.resolve()
  .then(() => {
    console.log('then 1')
    // 返回一个永远 pending 的 Promise
    return new Promise(() => {})
  })
  .then(() => {
    console.log('then 2') // 不会执行
  })
  .catch((err) => {
    console.log('catch', err) // 不会执行
  })

原理:根据 Promises/A+ 规范,当 then 的回调函数返回一个新 Promise 时,原 Promise 的状态会跟随新 Promise。如果新 Promise 保持 pending 状态,整个链路就会中止。

中断 Promise(超时控制)

使用 Promise.race 实现超时中断,常用于网络请求:

function timeoutWrapper(p, timeout = 2000) {
  const wait = new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('请求超时')
    }, timeout)
  })
  return Promise.race([p, wait])
}

// 使用示例
const request = new Promise((resolve) => {
  setTimeout(() => resolve('请求成功'), 3000)
})

timeoutWrapper(request, 2000)
  .then(res => console.log(res))
  .catch(err => console.log(err)) // 输出:请求超时

关键点

  • Promise 本质上无法被终止,只能通过技巧实现”中断”效果
  • 返回永远 pending 的 Promise 可以阻止调用链继续执行
  • Promise.race 配合定时器可以实现超时控制
  • 抛出错误只会跳转到 catch,无法真正中断链路