You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何await在fetch与自定义函数调用中的表现存在差异?

为什么fetch错误与自定义函数调用错误的表现存在差异?

两种场景的行为对比

场景1:自定义Promise拒绝函数

调用返回Promise.reject的自定义函数时,await会触发未捕获错误,导致后续代码终止执行:

function call()
{
  return Promise.reject("done")
}

React.useEffect(()=>{
  async function check(){
    const x = await call();
    console.log(x);
    console.log("finished");
  };
  check();
},[])

这里控制台不会输出"finished",因为await call()抛出的错误未被捕获,check函数直接终止运行。

场景2:fetch请求

即便请求返回HTTP错误状态码(比如404),fetch的Promise仍会处于resolved状态,后续代码正常执行:

React.useEffect(()=>{
    async function check(){
      const x = await fetch("https://www.thecocktaildb.com/api/json/v1/1/");
      console.log(x);
      console.log("finished");
    };
    check();
  },[])

控制台会输出Response对象和"finished"。


核心原因分析

  • 自定义函数的行为:call()直接返回了一个rejected状态的Promise。当await遇到rejected Promise时,会将其转化为同步错误抛出;如果没有用try/catch捕获这个错误,当前async函数会立即停止执行,后续代码自然不会运行。

  • fetch的设计逻辑:fetch的Promise仅在网络层面彻底失败时才会reject(比如DNS解析失败、无法建立TCP连接)。对于HTTP错误状态码(4xx、5xx),fetch认为请求已经完成,会返回一个resolved的Response对象,只是这个对象的ok属性为false,status属性对应具体的错误状态码。因此await fetch(...)不会抛出错误,后续代码可以继续执行。

如果需要让fetch在HTTP错误时也触发错误逻辑,需要手动判断Response状态并抛出错误:

React.useEffect(()=>{
  async function check(){
    try {
      const x = await fetch("https://www.thecocktaildb.com/api/json/v1/1/");
      if (!x.ok) {
        throw new Error(`请求失败:${x.status}`);
      }
      console.log(x);
      console.log("finished");
    } catch (err) {
      console.error(err);
    }
  };
  check();
},[])

内容的提问来源于stack exchange,提问作者Karan Guleria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 05:32:22