概述
在使用異步的終極解決方案-ES7的async/await同時,如何優(yōu)雅的處理錯誤提高代碼的兼容性讓作為碼農(nóng)的我很頭疼。在項(xiàng)目實(shí)戰(zhàn)中合理的使用try...catch...讓代碼的兼容和穩(wěn)定性大大增強(qiáng)。
本文將對 try...catch... 從為什么要用->到如何使用->實(shí)戰(zhàn)三個方面來敘述。
1、為什么要用 try...catch...
async function funcAsync(){
console.log('\n---begin---\n');
await ih_func();
console.log('------end-----');
}
function ih_func(){
return new Promise(function (resolve, reject) {
//這里相當(dāng)于throw一個異常了
reject('error');
});
}
funcAsync();

你一定會好奇為什么只打印了begin而沒有打印end,這是因?yàn)閞eject('error'); 相當(dāng)于throw一個異常了,所以程序就不會繼續(xù)往下執(zhí)行了,想要程序繼續(xù)執(zhí)行下去就需要處理throw出來的異常。
2、如何使用 try...catch... 處理異常
async function funcAsync(){
console.log('\n---begin---\n');
try{
await ih_func();
} catch(e){
console.log(e);
}
console.log('------end-----');
}
function ih_func(){
return new Promise(function (resolve, reject) {
//這里相當(dāng)于throw一個異常了
reject('error');
});
}
funcAsync();

驚奇的發(fā)現(xiàn)通過 try...catch... 處理異常后的程序神奇的執(zhí)行完成了。
在try{}中的代碼 throw 出來的異常會被 catch 捕獲到,程序認(rèn)為你處理異常了,所以繼續(xù)往下執(zhí)行了
2、 try...catch... 之實(shí)戰(zhàn)
-
程序如何處理異常
async function funcAsync(){
for(let i=0; i<3; i++){
try{
console.log('\n---begin---\n');
await ih_func();
console.log('------end-----');
} catch(e){
console.log(e);
}
console.log('-----end2-----');
}
}
function ih_func(){
return new Promise(function (resolve, reject) {
//這里相當(dāng)于throw一個異常了
reject('error');
});
}
funcAsync();

上面代碼運(yùn)行代碼后發(fā)現(xiàn),當(dāng) ih_func() throw出異常后,被外層的catch捕獲并處理,而且直接跳出打印end2。并沒有我們預(yù)期中,繼續(xù)往下執(zhí)行打印end。
-
多層try...catch... 如何處理異常
async function funcAsync_1(){
try{
await funcAsync_2();
} catch(e){
console.log('funcAsync_1');
console.log(e);
}
console.log('funcAsync_1 ---- end');
}
async function funcAsync_2(){
for(let i=0; i<3; i++){
console.log('\n---begin'+ i +'---\n');
try{
await ih_func(i);
} catch(e){
console.log(e);
}
console.log('------end'+ i +'-----');
}
}
function ih_func(args){
return new Promise(function (resolve, reject) {
//這里相當(dāng)于throw一個異常了
reject('error' + args);
});
}
funcAsync_1();

-
結(jié)論
一層 try...catch...的時候: 當(dāng)程序 throw 出異常后,被外層的catch捕獲并處理,程序在catch捕獲處繼續(xù)執(zhí)行下去。
多層try...catch...的時候:當(dāng)程序 throw 出異常后,會被離異常最近的catch捕獲并處理,程序在catch捕獲處繼續(xù)執(zhí)行下去。
當(dāng)程序throw出一個異常后,會從里往外一直尋找處理異常的catch,當(dāng)找到離異常最近的catch時,會被這個catch處理,并不會再往外傳遞異常,而且會在catch處理當(dāng)前代碼行繼續(xù)往下執(zhí)行。
-
如何提高程序的健壯性
async function funcAsync(){
for(let i=0; i<3; i++){
console.log('\n---begin'+ i +'---\n');
try{
await ih_func(i);
} catch(e){
console.log(e);
}
console.log('------end'+ i +'-----');
}
}
function ih_func(args){
return new Promise(function (resolve, reject) {
//這里相當(dāng)于throw一個異常了
reject('error' + args);
});
}
funcAsync();

對于多個await Promise返回值的時候,可以對具有Promise返回值為reject的異步操作時,使用 try...catch...不僅可以增強(qiáng)代碼的健壯性,而且使代碼在我們預(yù)期中執(zhí)行下去。
示例代碼
https://github.com/yangxiaopingios/koaExample/blob/master/code/script/twoExample.js