promise和try catch的比较

Promise 和 try-catch 不是同一层面的东西 ,它们解决不同的问题,但经常被放在一起比较的是 Promise 的错误处理(.catch)try-catch 同步错误捕获

核心区别

特性 try-catch Promise.catch
捕获错误类型 同步代码 异步代码(Promise 链)
语法 语句块 方法链
能否捕获异步错误 ❌ 不能 ✅ 能

关键示例:try-catch 无法捕获异步错误

javascript 复制代码
// ❌ try-catch 无法捕获异步错误
try {
  setTimeout(() => {
    throw new Error('异步错误');  // 这里抛出错误时,try-catch早已执行完毕
  }, 1000);
} catch (err) {
  console.log('捕获不到:', err);  // 永远不会执行
}

// ✅ Promise.catch 可以捕获
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('异步错误'));  // 通过 reject 传递错误
  }, 1000);
});
promise.catch(err => {
  console.log('捕获到了:', err);  // 能捕获
});

// ✅ 或者使用 async/await + try-catch
async function test() {
  try {
    await promise;  // await 把异步错误转成了可捕获的同步错误
  } catch (err) {
    console.log('用 try-catch 也能捕获了', err);
  }
}

各自的使用场景

try-catch 适合:

javascript 复制代码
// 1. 同步代码
try {
  JSON.parse('invalid json');
  const result = 1 / 0;
  if (someVar === undefined) throw new Error('自定义错误');
} catch (err) {
  console.error(err);
}

// 2. async/await 中的异步代码
async function fetchData() {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    return data;
  } catch (err) {
    console.log('请求失败', err);
  }
}

Promise.catch 适合:

javascript 复制代码
// 1. Promise 链式调用
fetch('/api/user')
  .then(res => res.json())
  .then(data => processData(data))
  .catch(err => {
    console.error('某个环节出错', err);
  });

// 2. 多个独立的 Promise(Promise.all)
Promise.all([
  fetch('/api/user'),
  fetch('/api/posts'),
  fetch('/api/comments')
])
.then(results => console.log('全部成功', results))
.catch(err => console.log('任意一个失败', err));

混合使用的常见模式

javascript 复制代码
// 在 async 函数中,可以用 try-catch 代替 .catch
async function getData() {
  try {
    const user = await fetchUser();      // 可能 reject
    const posts = await fetchPosts();    // 可能 reject
    return { user, posts };
  } catch (error) {
    // 统一处理任何一个 await 的错误
    console.error('出错了:', error);
    return null;
  }
}

// 等价于 Promise 写法
function getData() {
  return fetchUser()
    .then(user => Promise.all([user, fetchPosts()]))
    .then(([user, posts]) => ({ user, posts }))
    .catch(error => {
      console.error('出错了:', error);
      return null;
    });
}

实际项目中的推荐写法

javascript 复制代码
// 1. 顶层异步函数:用 try-catch(更清晰)
async function handleRequest() {
  try {
    const data = await apiCall();
    updateUI(data);
  } catch (err) {
    showErrorToast(err.message);
  } finally {
    hideLoading();  // 无论成功失败都执行
  }
}

// 2. 链式操作较多时:用 .catch(更链式)
apiCall()
  .then(transformData)
  .then(validateData)
  .then(saveToStore)
  .catch(handleError);

// 3. 同时捕获同步和异步错误
async function robustFunction() {
  try {
    // 同步错误也能捕获
    if (!input) throw new Error('输入为空');
    
    // 异步错误也能捕获
    const result = await asyncOperation();
    
    return result;
  } catch (err) {
    // 统一处理所有错误
    return fallbackValue;
  }
}

总结

  • 不能互相替代:try-catch 管同步,Promise.catch 管异步 Promise
  • 最佳实践 :使用 async/await + try-catch 能让异步代码看起来像同步代码,错误处理也更统一
  • 记住await 是关键,它把 Promise 的 reject 转换成了可以被 try-catch 捕获的异常
相关推荐
搬砖的码农2 小时前
(08)为什么我的 Agent 一跑后台服务就卡死
前端·agent·ai编程
飘尘2 小时前
前端转全栈(Java 后端)必须要知道的:开发中的锁机制与分布式并发控制
前端·后端·全栈
亲亲小宝宝鸭2 小时前
前端性能监控:web-vitals
前端·性能优化·监控
陆枫Larry2 小时前
可滚动页面背景填不满:`height: 100vh` vs `min-height: 100vh`
前端
Patrick_Wilson2 小时前
Squash Merge 的血缘陷阱:为什么删掉的代码又活了过来
前端·git·程序员
kyriewen3 小时前
今天的科技圈,全在抢英伟达的饭碗
前端·面试·ai编程
SouthernWind3 小时前
RAGFlow——结合本地知识库检索开发实战指南(包含聊天、检索本地的知识库文档和Agent模式)
前端
三翼鸟数字化技术团队4 小时前
websocket及SSE原理解析
前端