async/await 错误处理的陷阱有哪些?如何避免?

AI 概述
陷阱一:忘记使用 try/catch 捕获错误陷阱二:在 Promise 链中丢失错误陷阱三:在循环中的错误处理不当陷阱四:不处理异步函数中的同步错误陷阱五:未考虑 await 表达式返回的 Promise 状态 我们在前端开发过程中经常会用到async/await,async/await让 JavaScript 异步编程变得更加直观和优雅。然而,...
目录
文章目录隐藏
  1. 陷阱一:忘记使用 try/catch 捕获错误
  2. 陷阱二:在 Promise 链中丢失错误
  3. 陷阱三:在循环中的错误处理不当
  4. 陷阱四:不处理异步函数中的同步错误
  5. 陷阱五:未考虑 await 表达式返回的 Promise 状态

我们在前端开发过程中经常会用到async/awaitasync/await让 JavaScript 异步编程变得更加直观和优雅。然而,在处理错误时,这种语法糖也隐藏了许多容易被忽视的陷阱。作为一名经历过无数深夜紧急修复的前端开发者,分享下个人生产环境中亲身经历的 5 个async/await错误处理陷阱,以及如何避免它们。

async/await 错误处理的陷阱有哪些?如何避免?

陷阱一:忘记使用 try/catch 捕获错误

最常见也最基础的错误是完全忘记处理异步操作中可能发生的异常。

async function fetchUserData(userId) {
  const response = await fetch(`/api/users/${userId}`);
  const userData = await response.json();  // 如果响应不是有效 JSON 会抛出错误
  return userData;
}

这段代码在遇到网络错误、服务器错误或无效 JSON 时会直接抛出未捕获的异常,可能导致整个应用崩溃。

正确做法

async function fetchUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const userData = await response.json();
    return userData;
  } catch (error) {
    console.error(`获取用户数据失败: ${error.message}`);
    // 返回默认值或重新抛出错误
    throw new Error(`获取用户 ID ${userId} 的数据失败: ${error.message}`);
  }
}

陷阱二:在 Promise 链中丢失错误

当混合使用async/await.then()/.catch()链式调用时,错误处理会变得混乱。

async function processData() {
  const rawData = await fetchData();

  // 错误:以下的错误不会被当前函数的 try/catch 捕获
  processResult(rawData).then(result => {
    // 使用结果...
  });
}

正确做法

async function processData() {
 try {
    const rawData = await fetchData();

    // 方法一:在链中添加错误处理
    processResult(rawData)
      .then(result => {
        // 使用结果...
      })
      .catch(error => {
        console.error("处理结果时出错:", error);
      });

    // 方法二(更好):完全使用 await
    const result = await processResult(rawData);
    // 使用结果...
  } catch (error) {
    console.error("处理数据失败:", error);
  }
}

陷阱三:在循环中的错误处理不当

在循环中使用async/await时,错误处理尤其复杂。

async function processItems(items) {
    try {
        for(const item of items) {
            // 如果这里抛出错误,后面的项目都不会被处理
            await processItem(item);
        }
    } catch (error) {
        console.error("处理项目时出错:",error);
    }
}

一个项目的错误会中断整个处理流程,这可能不是你想要的行为。

正确做法

async function processItems(items) {
    const results = [];
    const errors =[];
    for(const item of items) {
        try {
            const result = await processItem(item);
            results.push(result);
        } catch (error) {
            console.error(`处理项目 ${item.id} 时出错:`, error);
            errors.push({ item, error });
        }
    }
    return { results, errors };
}

或者使用Promise.allSettled处理并行操作:

async function processItems(items){
    const promises = items.map(item => processItem(item));
    const outcomes = await Promise.allSettled(promises);
    const results = outcomes
      .filter(outcome => outcome.status === "fulfilled")
      .map(outcome => outcome.value);
    const errors = outcomes
      .filter(outcome => outcome.status === "rejected")
      .map((outcome, index) => ({ item: items[index], error: outcome.reason }));

    return{ results, errors };
}

陷阱四:不处理异步函数中的同步错误

一个常见误解是认为try...catch只能捕获await表达式的错误,而忽略了同步代码也会抛出错误。

async function processUserData(userId) {
    const userData = await fetchUserData(userId);
    // 如果 userData 为 null 或 undefined,这里会抛出错误
    const formattedData = formatUserData(userData);
    return formattedData;
}

正确做法

async function processUserData(userId) {
    try {
        const userData = await fetchUserData(userId);
        if (!userData ){
            throw new Error(`没有找到 ID 为 ${userId} 的用户数据`);
        }
        const formattedData = formatUserData(userData);
        return formattedData;
    } catch (error) {
        console.error(`处理用户 ${userId} 的数据时出错:`, error);
        // 适当的错误处理...
        throw error; // 或者返回默认值
    }
}

陷阱五:未考虑 await 表达式返回的 Promise 状态

await表达式可能返回已解决的Promise,但其值可能表示错误状态。

async function fetchResource() {
    const response = await fetch('/api/resource');
    // 错误: 即使状态码是 404 或 500,这里也不会抛出错误
    const data = await response.json();
    return data;
}

正确做法

async function fetchResource() {
 try {
    const response = await fetch('/api/resource');
    
    if (!response.ok) {
      throw new Error(`API 错误: ${response.status} ${response.statusText}`);
    }
    
    const data = await response.json();
    return data;
  } catch (error) {
    console.error("获取资源失败:", error);
    throw error;
  }
}

以上就是今天为大家整理的关于async/await错误处理的陷阱,如果大家有其他的,欢迎补充。

以上关于async/await 错误处理的陷阱有哪些?如何避免?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » async/await 错误处理的陷阱有哪些?如何避免?

发表回复