为何async函数中返回的Promise.reject无法被内部try-catch捕获?
问题分析与解决
你的问题出在两个核心点上:
1. fetch的特性让try/catch没捕获到404
fetch API 只有在网络层面失败(比如断网、域名无法解析)时才会抛出rejected状态的Promise。像404、500这类HTTP状态码错误,fetch依然会返回resolved状态的Promise——也就是说你代码里的try/catch块根本没触发,catch里的console.log(err)从来没执行过。
2. 返回的Promise.reject未被处理
当res.ok为false时,你返回了Promise.reject(res.status),这会让getData()最终返回一个rejected状态的Promise。但你调用getData()时只加了.then(),没有对应的.catch()处理这个reject,所以浏览器会把这个未捕获的Promise拒绝抛出Uncaught (in promise)错误,你看到的“404”就是这个reject的原因。
修复方案
有两种可行的解决方式:
方式一:在getData()内部捕获并处理错误
把Promise.reject换成主动抛出错误,让try/catch能捕获到,同时返回兜底值避免外部Promise处于rejected状态:
const getData = async() => { const url = "https://dummyjson.com/quotees?limit=20"; try { const res = await fetch(url); if (!res.ok) { throw new Error(res.status); // 主动抛出错误进入catch } return res.json(); } catch(err) { console.log(err.message); // 这里会直接输出404 return null; // 返回兜底值,确保外部Promise是resolved状态 } }; getData() .then(d => { if (d) d.quotes.forEach(q => ...); });
方式二:在外部调用时添加.catch()处理reject
如果希望getData()保留reject状态,就在调用链末尾补上catch:
const getData = async() => { const url = "https://dummyjson.com/quotees?limit=20"; const res = await fetch(url); return res.ok ? res.json() : Promise.reject(res.status); }; getData() .then(d => { if (d) d.quotes.forEach(q => ...); }) .catch(err => { console.log(err); // 这里会输出404,不会出现Uncaught错误 });
内容的提问来源于stack exchange,提问作者AbsoluteBeginner
相关产品推荐
相关产品推荐

