async,await是es7新增的api,比es6的promise更加優雅,但是最近在使用await時發現處理錯誤並不像promise這么簡單,下面是簡單的應用示例。
首先,我們先模擬幾個異步的操作
var p1 = function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log('p1') resolve('p1 success'); }, 2000) }) } var p2 = function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log('p2') reject('p2 fail'); }, 1000) }) } var p3 = function () { console.log('p3') }
然后我們看使用es6的promise處理異步操作並捕獲錯誤
//用promise控制執行流程 var test = function () { p1() .then(function () { p2() .then(function () { p3() }).catch(function (e) { console.log('p2失敗了', e) }) }).catch(function (e) { console.log('p1失敗了', e) }) } //用promise.all控制執行流程 var test1 = function () { Promise.all([p1(), p2()]) .then(function () { p3(); }).catch(function (e) { console.log('p1或者p2失敗了', e) }) }
這樣寫可以很好地處理錯誤,但是並不美觀,所以我們要使用async,await,使其更像同步代碼
//用await來控制流程,看着比用promise控制要優雅簡介許多,但是並沒有處理錯誤 var test2 = async function () { await p1(); await p2(); p3(); }
這樣確實優雅了很多,但是如何處理錯誤呢?我們用try,catch語句來捕獲錯誤
//用try,catch處理報錯,但是try catch用多了會影響性能,並且這樣寫也很不美觀 var test3 = async function () { try { await p1(); await p2(); p3(); } catch (e) { console.log('p1失敗了', e) } }
try catch可以捕獲錯誤,但是這樣寫還是不夠美觀,並且用多了會有性能問題,所以我們就到了重點,今天的to方法
//使用async/await時處理報錯的方法 function to(promise) { if (!promise || !Promise.prototype.isPrototypeOf(promise)) { return new Promise((resolve, reject) => { reject(new Error("requires promises as the param")); }).catch((err) => { return [err, null]; }); } return promise.then(function () { console.log(arguments,'arguments') return [null, ...arguments]; }).catch(err => { return [err, null]; }); }
封裝的to方法,原理是用promise的then,catch方式捕捉錯誤並拋出,使用方式是這樣的
//用to方法處理錯誤信息,代碼也比較看着整潔易懂 var test4 = async function () { let [err1, res1] =await to(p1()); if (err1) { console.log('p1失敗了', err1); return false; } let [err2,res2] =await to(p2()); if(err2){ console.log('p2失敗了',err2); return false; } p3(); }
這樣代碼是不是優雅了很多,並且性能也好些。