返回

Promise 实现细节探索:Promise.prototype.catch 和 Promise.prototype.finally 的秘密

前端

深入探索 Promise.prototype.catch 和 Promise.prototype.finally

Promise.prototype.catch

当 Promise 被拒绝时,catch 方法被用来处理错误。它接受一个回调函数,当 Promise 失败时执行,并传递失败原因作为参数。

const promise = Promise.reject(new Error('Oops!'));

promise.catch((error) => {
  console.log(`错误:${error.message}`);
});

catch 方法是如何工作的?

Promise.prototype.catch = function(onRejected) {
  return this.then(undefined, onRejected);
};
  • catch 方法实际上是调用了 then 方法。
  • 它将 undefined 作为第一个参数(表示成功处理程序),将回调作为第二个参数(表示拒绝处理程序)。

Promise.prototype.finally

finally 方法无论 Promise 成功还是失败都会执行一个回调。

const promise = Promise.resolve(42);

promise.finally(() => {
  console.log('总是会被调用!无论结果如何');
});

finally 方法是如何工作的?

Promise.prototype.finally = function(onFinally) {
  return this.then(
    (value) => {
      return Promise.resolve(onFinally()).then(() => value);
    },
    (error) => {
      return Promise.resolve(onFinally()).then(() => { throw error; });
    }
  );
};
  • finally 方法也是调用 then 方法。
  • 对于成功的 Promise,它先调用 finally 回调,然后返回一个解决为 Promise 结果的 Promise。
  • 对于失败的 Promise,它先调用 finally 回调,然后返回一个抛出错误的 Promise。

结论

catchfinally 方法为处理 Promise 的成功和失败提供了一种方便的方式。理解它们的内部机制可以帮助我们更有效地使用 Promise。

常见问题解答

1. catch() 和 then() 的区别是什么?

  • catch() 只处理失败的 Promise,而 then() 可以处理成功和失败的 Promise。

2. finally() 什么时候有用?

  • 当我们需要在 Promise 完成后执行一些清理或副作用时,finally() 很有用。

3. catch() 会阻止 finally() 被执行吗?

  • 否,无论 Promise 成功与否,finally() 都会被执行。

4. 可以将 catch() 链在一起吗?

  • 否,catch() 只捕获一次错误,不能链式调用。

5. 如何处理未捕获的 Promise 拒绝?

  • 可以使用 window.addEventListener('unhandledrejection', ...) 来处理未捕获的拒绝。