跳至主要內容

PromiseThenCatch

chanchaw大约 2 分钟javascript

概述

then 接受两个参数依次是成功和失败的回调函数,两者都是可选的。catch 作用同then 的第二个参数(失败的回调函数)也是用来处理失败的方法,不同的是 catch 可用于链式调用时捕捉整个链路上出现的异常,而 then 的第二个参数(失败的回调函数)只能处理当前异步请求的异常。

案例

then两个参数的案例

// promise 语法
promise.then(
  onFulfilled, // 成功回调
  onRejected   // 失败回调(可选)
);

// 案例
// 1. 创建一个 promise 对象
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = true; // 模拟操作是否成功
    if (success) {
      resolve("Operation succeeded!"); // 成功时调用 resolve
    } else {
      reject("Operation failed!"); // 失败时调用 reject
    }
  }, 1000);
});
// 2. 填充两个参数:成功回调、失败回调
promise.then(
  (result) => {
    console.log("Success:", result); // 成功时执行
  },
  (error) => {
    console.error("Failure:", error); // 失败时执行
  }
);

catch案例

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = false; // 模拟操作失败
    if (success) {
      resolve("Operation succeeded!");
    } else {
      reject("Operation failed!");
    }
  }, 1000);
});

promise
  .then((result) => {
    console.log("Success:", result); // 成功时执行
  })
  .catch((error) => {
    console.error("Failure:", error); // 失败时执行
  });

链式调用中的catch

用于处理 Promise 失败的情况,通常放在链式调用的最后

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true; // 模拟操作是否成功
      if (success) {
        resolve({ data: "Some data" });
      } else {
        reject("Failed to fetch data");
      }
    }, 1000);
  });
};

fetchData()
  .then((response) => {
    console.log("Data received:", response.data);
    return response.data.toUpperCase(); // 返回处理后的数据
  })
  .then((processedData) => {
    console.log("Processed data:", processedData);
  })
  .catch((error) => {
    console.error("Error:", error);
  });

混合捕获错误

const promise = new Promise((resolve, reject) => {
  resolve(10);
});

promise
  .then((result) => {
    console.log("First .then():", result);
    throw new Error("Error in first .then()"); // 抛出错误
  })
  .then(
    (result) => {
      console.log("Second .then():", result);
    },
    (error) => {
      console.error("Error in second .then():", error); // 不会捕获到错误
    }
  )
  .catch((error) => {
    console.error("Error in .catch():", error); // 捕获到错误
  });

最佳实践

  • 推荐使用 .catch():将错误处理逻辑集中放在链式调用的末尾,代码更清晰易读。
  • 避免混用 .then() 的第二个参数和 .catch():混用可能会导致错误处理逻辑分散,增加代码的复杂性。

推荐写法

promise
  .then((result) => {
    console.log("Success:", result);
  })
  .then((result) => {
    console.log("Next step:", result);
  })
  .catch((error) => {
    console.error("Error:", error);
  });

try...catch

// 语法
try {
  // 可能会抛出错误的代码
} catch (error) {
  // 捕获并处理错误
} finally {
  // 无论是否抛出错误,都会执行的代码(可选)
}

一般结合 async/await 使用

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject("Failed to fetch data!"); // 模拟异步操作失败
    }, 1000);
  });
};

async function getData() {
  try {
    const data = await fetchData(); // 等待 Promise 完成
    console.log("Data:", data);
  } catch (error) {
    console.error("Error:", error); // 捕获异步错误
  }
}

getData();

注意

  • 只能捕获同步错误try...catch 只能捕获同步代码中的错误。对于异步代码(例如 setTimeoutPromise),需要使用 async/await.catch() 来处理错误。
  • 不要滥用 try...catchtry...catch 适用于处理预期可能发生的错误,而不是用于控制程序流程。