const api = {
getData: () => {
return new Promise((resolve) => {
resolve(undefined);
});
},
};
沒有異常處理,會導致程序崩潰
const getLogo = async () => {
const res = await api.getData()
return res.logo
}
const main = async () => {
const logo = await getLogo()
}
main()
加異常處理,但只是簡單打印錯誤信息,程序沒有崩潰,並且輸出的錯誤信息
const getLogo = async () => {
try {
const res = await api.getData()
return res.logo
} catch (error) {
// 打印異常信息
console.error(`getLogo error: ${error}`)
}
}
const main = async () => {
const logo = await getLogo()
}
main()
在前面的基礎上添加業務邏輯,雖然沒有崩潰,但是我們會發現,在getLogo已經失敗的情況下,還是執行了copyLogoToDist,這顯然是不合理的,我們的做法簡單來説只是把異常吞掉了,這會導致後續邏輯在錯誤狀態下繼續執行,可能引發更嚴重的問題
const getLogo = async () => {
try {
const res = await api.getData()
return res.logo
} catch (error) {
// 打印異常信息
console.error(`getLogo error: ${error}`)
}
}
const copyLogoToDist = async (logo) => {
console.log('copyLogoToDist')
// ...
}
const main = async () => {
const logo = await getLogo()
await copyLogoToDist(logo)
}
main()
那麼如何解決上面的問題呢?
方案有兩種:
方案1:判斷getLogo的返回值,也就是logo,然後決定是否執行copyLogoToDist
方案2:在getLogo中拋出異常,讓調用者處理
方案1示例:
const getLogo = async () => {
try {
const res = await api.getData()
return res.logo
} catch (error) {
// 打印異常信息
console.error(`getLogo error: ${error}`)
}
}
const copyLogoToDist = async (logo) => {
console.log('copyLogoToDist')
// ...
}
const main = async () => {
const logo = await getLogo()
// 由於getLogo吞掉了異常,沒有做其他操作,所以getLogo的返回值將會是undefined
// 這裏的判斷就避免了將異常被延續了
if (logo) {
await copyLogoToDist(logo)
}
}
main()
方案2示例:
const getLogo = async () => {
try {
const res = await api.getData()
return res.logo
} catch (error) {
console.error(`getLogo error: ${error}`)
// 拋出異常
thrown error
}
}
const copyLogoToDist = async (logo) => {
console.log('copyLogoToDist')
// ...
}
const main = async () => {
// 在調用處處理異常,當getLogo拋出了異常,就避免了將異常繼續延續下去
try {
const logo = await getLogo()
await copyLogoToDist(logo)
} catch (error) {
console.error(`main error: ${error}`)
}
}
main()
方案1存在的問題:
1 if(logo)的意圖是用來判斷logo是否為合法值的,而不是處理異常的
2 如果getLogo不是一個沒有返回值的接口,那麼在這裏就無法處理了
const main = async () => {
// createLogo裏面發生了異常,在內部捕獲了
// createQuickEntry並不知道,然後繼續執行,導致異常被延續
await createLogo()
await createQuickEntry()
}
方案2可以解決方案1存在的問題
const main = async () => {
// createLogo拋出了異常,createQuickEntry就不會被執行了
try {
await createLogo()
await createQuickEntry()
} catch (err) {
console.error(`main error: ${error}`)
}
}