Promise 中 then 方法和 catch 方法的执行顺序

背景

前端开发中,异步操作的需求越来越常见。而在 JavaScript 中,Promise 是一种用于异步编程的语法,它允许我们以一种更加优雅和精确的方式来处理异步操作,有助于避免回调地狱的问题。 Promise 对象的状态至少有以下三种变化,分别是:pending(等待状态)、fulfilled(成功状态)和 rejected(失败状态)。

当 Promise 对象从 pending 状态转变为 resolved 状态后,会自动调用 then() 方法。如果 Promise 对象从 pending 状态转变为 rejected 状态,则会自动调用 catch() 方法。此外,then() 方法还可以链式调用,用于处理多个异步请求,这里咱们主要讲述原本一个then() 方法和一个 catch() 方法是如何串联执行的。

Promise.then() 和 Promise.catch() 的执行顺序

当 Promise 对象的状态由 pending 转变为 fulfilled 时,then() 方法会被自动执行,如果在 then() 方法中抛出了异常,或者 then() 方法返回的是一个 rejected 状态的 Promise 对象,那么 catch() 方法就会被自动执行。以下是一个简单的示例:

let promise = new Promise((resolve, reject) => {
  // simulate an asynchronous operation
  setTimeout(() => {
    resolve("Completed success!");
  }, 1000);
});

promise.then((result) => {
  console.log(result); //Completed success!
  throw new Error("This is an exception occurred in then() method.");
}).catch((error) => {
  console.error(error); //This is an exception occurred in then() method.
});

总结

在使用 Promise 进行异步操作的开发中,我们需要了解 Promise.then() 和 Promise.catch() 的执行顺序,这有助于我们在编写代码时正确的处理异步操作。当 Promise 对象的状态从 pending 转变为 fulfilled 时,会自动调用 then() 方法,如果在 then() 方法中抛出了异常,或者 then() 方法返回的是一个 rejected 状态的 Promise 对象,那么 catch() 方法就会被自动执行。因此,在编写 then() 和 catch() 方法时,我们需要非常小心和仔细,避免抛出异常和返回 rejected 状态的 Promise 对象。

上面示例代码展示了then() 方法中抛出异常和返回失败状态的 Promise 对象都会执行catch() 方法的情况。最后看到通常的回调地狱是这样的:

$.ajax({
  url: "xxx",
  success: function (result) {
    $.ajax({
      url: "xxx",
      success: function (result) {
        $.ajax({
          url: "xxx",
          success: function (result) {
              // ...
          },
          error: function (err) {
              console.log(err);
          }
        });
      },
      error: function (err) {
          console.log(err);
      }
    });
  },
  error: function (err) {
      console.log(err);
  }
});

而 Promise 可以通过链式调用避免这个问题,这样代码会更加优雅,也会更加可读。

new Promise((resolve, reject) => {
  ajax({
    url: "xxx",
    method: "GET",
    success: function (result) {
      resolve(result);
    },
    error: function (err) {
      reject(err);
    },
  });
})
  .then((res) => {
    // ...
    return new Promise((resolve, reject) => {
      ajax({
        url: "xxx",
        method: "GET",
        success: function (result) {
          resolve(result);
        },
        error: function (err) {
          reject(err);
        },
      });
    });
  })
  .then((res) => {
    // ...
    return new Promise((resolve, reject) => {
      ajax({
        url: "xxx",
        method: "GET",
        success: function (result) {
          resolve(result);
        },
        error: function (err) {
          reject(err);
        },
      });
    });
  })
  .catch((err) => {
    console.log(err);
  });

指导意义

了解 Promise.then() 和 Promise.catch() 的执行顺序,以及 Promise 中 then() 方法的链式调用,能够帮助我们更加深入的理解 Promise 的运行机制,为我们更加快速高效地开发和维护异步代码提供便利。同时通过避免回调地狱等问题,使得代码的可读性更强,让我们专注于业务逻辑的实现,提升开发效率和代码质量。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a32b61add4f0e0ffb45dfb


纠错反馈