async await 处理报错的方式

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();
  }

这样代码是不是优雅了很多,并且性能也好些。

原文地址:https://www.cnblogs.com/lijianjian/p/9718529.html