Appearance
使用async/await请务必添加try/catch
最早前端接口请求调用比较费劲,我想大家从初学者的时候都使用过"回调地狱"。
js
queryData(url, () => {
getData(url, () => {
fetchData(url, () => {
loadData(url, () => {
...
})
})
})
})
尤其是在Jquery时期这种代码非常的多,但是大家也没有什么太好的办法,毕竟这种连续的请求就是需要如此。
后来进入到 Promise 以后,可以使用连续的 then() 方法来进行处理,结构上显得优化了很多。
js
getData(url).then()
.then(() => getData(url))
...
到现在直接使用 async/await,从结构上看显得更加的优雅了。
async/await 是 Js中用于处理异步操作的一种语法糖。它建立在 Promise 的基础之上,旨在让异步代码的编写和阅读体验更像同步代码。
async/await工作流程
- 函数调用:当你调用一个
async
函数时,它立即返回一个Pending
状态的Promise
。 - 执行函数体:
async
函数的执行体开始运行。 - 遇到
await
:当执行到await promiseExpression
时,判断返回的Promise
状态,如果是fulfilled
则继续执行,如果是pending
则暂停执行,并等待Promise
状态改变。
但是,为什么在async/await中一定要添加try/catch呢?
先打个比方:你在家点了一份外卖(这就像一个异步操作,比如请求服务器数据):
javascript
async function 点外卖() {
const 外卖 = await 叫外卖(); // 等待外卖送达
console.log("收到外卖啦:", 外卖);
}
这个过程看起来很顺利,但现实是:
- 外卖小哥可能迷路了 🚴
- 餐厅可能做不出来这道菜 🍝
- 支付可能失败 💳
- 快递可能被偷了 🚨
这些就是“异常情况”,也就是程序里的 错误(Error)或拒绝(Rejected)的 Promise。
如果程序遇到错误,但你没有处理它,那么程序崩溃!
就像你点了外卖,结果没人告诉你失败了,你一直饿着等,也不知道怎么回事。
await
的本质是:
“我在这里等一下,等前面那个异步任务(Promise)完成。如果它成功了,我就拿到结果继续往下走;如果它失败了……”
⚠️ 重点来了:如果 await
后面的 Promise 被 reject(失败),JavaScript 会把这个错误当作一个“异常”抛出来,就像你写代码时手动 throw new Error()
一样。
所以正确的做法是:用 try/catch 抓住错误
javascript
async function getData() {
try {
const response = await fetch('/api/user');
const user = await response.json();
console.log("用户信息:", user);
} catch (error) {
// 💡 错误被捕获了!你可以在这里处理它
console.error("哎呀,出问题了:", error.message);
alert("加载失败,请检查网络");
}
}
现在就像这样:
- 你点了外卖 🍔
- 结果餐厅说“卖完了”
- 你立刻收到通知:“抱歉,点不了”
- 你不会傻等,而是可以选择“换一家”或“改吃泡面”
这就是 try/catch
的作用:主动处理失败的情况,其实也就是咱们平时说的比较玄乎的防御性编程。
结语
虽然try/catch非常好用但是仍需要注意:
try/catch
只能捕获try
块内的await
错误。- 如果你在
async
函数里throw
错误,也会被catch
捕获。 - 即使用了
try/catch
,async
函数本身还是返回 Promise,推荐你也可以使用.then().catch()
。