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 捕获的异常
相关推荐
用户573240037231 小时前
AgentForge-WX v0.3.0:12项更新 + 框架重新定位,把微信小程序AI对话的坑全填了
前端
米丘1 小时前
HTTP 传输层 TCP 三次握手 / 四次挥手
前端·网络协议·http
小lan猫1 小时前
多域 RAG 知识库:从 Vue 前端到 NestJS + PGVector 的全栈实践
前端·人工智能·typescript
半个烧饼不加肉1 小时前
JS 底层探究--执行上下文
开发语言·前端·javascript
极光技术熊1 小时前
从零构建在线Excel:一个Java全栈工程师的实战记录
前端·后端
漂流技术客1 小时前
超详细!Vue3 + ECharts 快速实现地图可视化(附最新GeoJson地址)
前端·vue.js
山河木马2 小时前
无框架-原生webGL渲染-底层入门-1
前端·javascript·webgl
jingling5552 小时前
Flutter | 商城项目鸿蒙(OpenHarmony)适配实战
android·开发语言·前端·flutter·华为·harmonyos