问答题1072/1620如何中断Promise?

难度:
2021-07-31 创建

参考答案:

Promise 有个缺点就是一旦创建就无法取消,所以本质上 Promise 是无法被终止的,但我们在开发过程中可能会遇到下面两个需求:

  • 中断调用链

就是在某个 then/catch 执行之后,不想让后续的链式调用继续执行了。

somePromise
  .then(() => {})
  .then(() => {
    // 终止 Promise 链,让下面的 then、catch 和 finally 都不执行
  })
  .then(() => console.log('then'))
  .catch(() => console.log('catch'))
  .finally(() => console.log('finally'))

一种方法是在then中直接抛错, 这样就不会执行后面的then, 直接跳到catch方法打印err(但此方法并没有实际中断)。但如果链路中对错误进行了捕获,后面的then函数还是会继续执行。

Promise的then方法接收两个参数:

1Promise.prototype.then(onFulfilled, onRejected)

若onFulfilled或onRejected是一个函数,当函数返回一个新Promise对象时,原Promise对象的状态将跟新对象保持一致,详见Promises/A+标准。

因此,当新对象保持“pending”状态时,原Promise链将会中止执行。

1Promise.resolve().then(() => { 2 console.log('then 1') 3 return new Promise(() => {}) 4}).then(() => { 5 console.log('then 2') 6}).then(() => { 7 console.log('then 3') 8}).catch((err) => { 9 console.log(err) 10})
  • 中断Promise

注意这里是中断而不是终止,因为 Promise 无法终止,这个中断的意思是:在合适的时候,把 pending 状态的 promise 给 reject 掉。例如一个常见的应用场景就是希望给网络请求设置超时时间,一旦超时就就中断,我们这里用定时器模拟一个网络请求,随机 3 秒之内返回。

1function timeoutWrapper(p, timeout = 2000) { 2 const wait = new Promise((resolve, reject) => { 3 setTimeout(() => { 4 reject('请求超时') 5 }, timeout) 6 }) 7 return Promise.race([p, wait]) 8}

最近更新时间:2024-08-10

赞赏支持

题库维护不易,您的支持就是我们最大的动力!