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(); }
这样代码是不是优雅了很多,并且性能也好些。