async/await 错误处理的陷阱:生产环境踩过的5个坑


async/await让JavaScript异步编程变得更加直观和优雅。然而,在处理错误时,这种语法糖也隐藏了许多容易被忽视的陷阱。作为一名经历过无数深夜紧急修复的开发者,分享下生产环境中亲身经历的5个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时,错误处理尤其复杂。

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

** 正确做法 ** :

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

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

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

** 正确做法 ** :

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

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

** 正确做法 ** :

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;  
  }  
}  

欢迎补充。