为何请求数据的错误进入catch,手动返回的错误却进入then?
问题原因解析
核心差异在于你传给resolve的参数类型完全不同,这直接决定了外层Promise的状态走向:
第一个案例:API错误被catch捕获的原因
你在resolve中传入的是superAgent.get()返回的Promise对象:
const superAgent = require('superagent') async function getImage() { return new Promise((resolve, reject) => { resolve(superAgent.get('https://dooooog.ceo/api/breeds/image/random')) }) }
当你把一个Promise传给resolve时,外层的Promise会自动“接管”这个内部Promise的状态:
- 内部的superAgent请求因为端点错误失败,状态变为
rejected - 外层Promise会同步变成
rejected状态,所以后续的.catch()会触发,捕获到这个错误
另外补充:你的async函数本身就会返回Promise,完全没必要额外包裹一层new Promise,直接return superAgent.get(...)效果完全一致。
第二个案例:手动错误进入then的原因
你在resolve中传入的是Error实例对象,这只是一个普通的JS对象,不是Promise:
const superAgent = require('superagent') async function getImage() { return new Promise((resolve, reject) => { resolve(new Error('some error here')) }) }
此时外层Promise的状态是resolved,它的resolved值就是这个Error对象。.then()的作用就是接收Promise resolved状态的值,所以res.message能输出错误内容;而.catch()只有在Promise状态为rejected时才会执行,自然不会被触发。
如果想让这个错误被catch捕获,你应该调用reject(new Error('some error here')),而不是resolve。
关键总结
- 给
resolve传入Promise时,外层Promise会同步这个Promise的最终状态(resolved/rejected) - 给
resolve传入非Promise值(包括Error对象),外层Promise会进入resolved状态,值就是传入的内容 .catch()仅处理Promise被rejected的情况
内容的提问来源于stack exchange,提问作者Mabouelail
相关产品推荐
相关产品推荐

