为何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
相关产品推荐
相关产品推荐

