关于 promise 和 async/await 写法问题?
有一个关于 async
的写法问题, 如下:
定义了一个 api, fetchUser()
, 可以有两种写法:
第一种, 不进行错误的显示处理
const fetchUser = async () => {
const res = await axios.get('https://example.com')
return res.data
}
第二种, 使用try..catch
包裹
const fetchUser = async () => {
try {
const res = await axios.get('https://example.com')
return res.data
} catch (e) {
throw e.response
}
}
使用上貌似没有差别, 如下:
fetchUser()
.then(user => console.log(user))
.catch(err => console.error(err))
个人的疑惑在于错误的捕获和处理, 个人理解在于, 只要是出现了错误, 那么返回的 promise 对象就变成 reject, 只是第二个使用了 catch 捕获后包裹了一下错误信息再手动抛出. 第一种少些了一点代码...
所以想请教一下:
- 这两种写法有没有具体的差别, 或者说, 再更加复杂的异步情况下会有哪些不同?
- 使用哪种写法更加优雅?
若能解答, 不胜感激, 多谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在你这个情景下对调用者来说2个函数没差,你捕获错误又原样抛出多此一举。
但在大规模应用下你最外层得套一层
try catch
来统一处理错误吧?这个时候第二种写法就很有用了,可以额外加error_message
再throw
出去,让最外层迅速知道发生错误的是什么原因,问题出现在哪个函数,给出准确提示。你如果不做二次try catch
封装想实现这种效果就难度大了。你的问题不是不知道 async/await 与 Promise 的区别,是不知道怎么写
try...catch...
。try...catch...
的目的是捕获错误,并进行处理。发生错误 意味着开发者不知道接下来怎么做,只能抛出错误,让其它开发者处理。捕获错误 意味你明白接下来的代码有一些风险,你也打算处理发生的错误。具体到你的例子里,http request 可能面临网络断开、服务器出错、返回数据格式不对等错误,所以我们可以捕获这些错误,给出对应的提示。比如网络断开,就让用户联网;服务器出错,让用户等下再试试;格式不对,让用户反馈问题给某某。至于你怎么写,用 async/await 还是 promise,无所谓,没有什么区别。
但是你 catch 之后再抛出就莫名其妙了。
首先说你的个人疑惑和理解。
在大多数语言中,包括 JavaScript,没有 try catch 结构的函数就会直接抛出其过程中产生的异常。也就是说:
这二者是等效的。而你的例子中,第二种方式里 catch 了 e 之后,throw 出去的不是 e 本身,而是 e.response,所以一二方式不等效。
更加复杂的异步情况下会有哪些不同,哪种更优雅
当你需要同时执行两个异步流程的时候,这两种写法就会有明显不同,并且 Promise 写起来更舒服。
使用 Promise 的写法如下:
而由于配合 try catch 的 async/await 语法本身就旨在“用同步的方式编写异步流程”,所以这种场景明显不是他的强项:
而当你有两个异步流程要执行,且其中一个依赖于另一个的结果时,async/await 就更优雅。
希望对你有帮助。
第二种情况抛出的错误对象 是 第一种情况error对象的response属性。别的没有什么区别
async/await就是为了解决Promise写法不易理解,逻辑分离的缺点。功能上没什么不同,async/await更优雅,写出的代码更容易理解。
await axios.get('https://example.com').catch(err => console.error(err)) 可以这样写不用 try catch