Web前端之路让前端飞Web 前端开发

ES7 async/await 异常处理小技巧

2017-04-12  本文已影响1537人  Riophae

try/catch 存在一个问题是,捕获到的错误只在 catch 后面的块内可见,有些时候这会给编程带来一定的麻烦。例如:

function demo() {
  try {
    doSomeWork()
  } catch (err) {
    // err 只在 catch 块内可见
    console.error(err)
  }
  // 执行到这里 err 这个变量已经不存在了
  // 但是我们的代码逻辑可能需要在 catch 之后知道是否曾经发生错误
  if (!err) {
     // 如果没有发生错误才执行这里
  }
}

比较容易想到的一个解决方式是:

function demo() {
  let err // 把 err 声明提到外面,这样就可以在 try/catch 之后访问到它了
  try {
    doSomeWork()
  } catch (ex) {
    err = ex
  }
  if (!err) {
    // 如果没有发生错误才执行这里
  }
}

但是这样写比较麻烦。有没有更好的方式?请看下面代码:

function e(fn) {
  return function wrapped() {
    try {
      return [null, fn.apply(this, arguments)]
    } catch (err) {
      return [err]
    }
  }
}

function demo() {
  // 注意返回格式
  const [err, result] = e(doSomeWork)()
  if (!err) {
    // 如果没有发生错误才执行这里
  }
}

是不是简单多了 :D

此外,上面的逻辑还能应用在 async/await 上面:

function asyncWork(arg1, arg2) {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.5) resolve(arg1 + arg2)
    else reject('failure')
  })
}

async function demo1() {
  try {
    const result = await asyncWork(2, 3)
    return result
  } catch (err) {
    console.error(err)
  }
}

async function demo2() {
  const [err, result] = await e(asyncWork)(4, 5)
  if (err) {
    console.error(err)
  } else {
    return result
  }
}

function e(fn) {
  return async function (...args) {
    try {
      return [null, await fn.apply(this, args)]
    } catch (err) {
      return [err]
    }
  }
}

demo1()
demo2()
上一篇 下一篇

猜你喜欢

热点阅读