如何在写await async的时候不用try catch

Posted chrissong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在写await async的时候不用try catch相关的知识,希望对你有一定的参考价值。

在js的日常使用中,异步操作是经常会用到的,promise 和 await/async可以避免会掉地狱的痛苦。
我们可以用promise的链式回调处理异步结果,但是当有多个异步需要处理的时候也会避免不了要用一串的then函数来处理
 
function asyncTask(cb) {
   asyncFuncA.then(AsyncFuncB)
      .then(AsyncFuncC)
      .then(AsyncFuncD)
      .then(data => cb(null, data)
      .catch(err => cb(err));
}
 
这个时候可以用await/async来处理多个异步调用的情况
 
async function asyncTask(cb) {
    const user = await UserModel.findById(1);
    if(!user) return cb(‘No user found‘);
 
    const savedTask = await TaskModel({userId: user.id, name: ‘Demo Task‘});
    
    if(user.notificationsEnabled) {
         await NotificationService.sendNotification(user.id, ‘Task Created‘);  
    }
 
    if(savedTask.assignedUser.id !== user.id) {
        await NotificationService.sendNotification(savedTask.assignedUser.id, ‘Task was created for you‘);
    }
 
    cb(null, savedTask);
}

 

这样看的话异步可以像同步那样处理很简洁易读,但是错误的捕获却做不到,这里需要用到try/catch来做错误的处理
 
async function asyncTask(cb) {
    try {
       const user = await UserModel.findById(1);
       if(!user) return cb(‘No user found‘);
    } catch(e) {
        return cb(‘Unexpected error occurred‘);
    }
 
    try {
       const savedTask = await TaskModel({userId: user.id, name: ‘Demo Task‘});
    } catch(e) {
        return cb(‘Error occurred while saving task‘);
    }
 
    if(user.notificationsEnabled) {
        try {
            await NotificationService.sendNotification(user.id, ‘Task Created‘);  
        } catch(e) {
            return cb(‘Error while sending notification‘);
        }
    }
 
    if(savedTask.assignedUser.id !== user.id) {
        try {
            await NotificationService.sendNotification(savedTask.assignedUser.id, ‘Task was created for you‘);
        } catch(e) {
            return cb(‘Error while sending notification‘);
        }
    }
 
    cb(null, savedTask);
}

 

所以就成了上面这样,这样看来代码量和简洁程度都不是很友好,为了能够使异步可以像写同步一样易于理解,以及代码尽量简单减少嵌套,可以考虑封装一种函数拥有promise的便捷错误处理和await/async的简洁的写法,因为await 后面本来就是一个promise所以我们直接可以先处理promise 用catch来捕获error,在返回一个promise 交给await处理。
 
export default function to(promise) {
   return promise.then(data => {
      return [null, data];
   })
   .catch(err => [err]);
}
 

 

下面我们来测试一下这个方法的可行性
 
function taskPromise(status) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (status === "fail") {
            return reject("error")
          } else {
            return resolve("success")
          }
        }, 1000)
      })
  }
 
async function asyncTasks() {
     let err, result
     [err, result] = await to(taskPromise(""))
     if (err) {
        console.log("it‘s error")
     } else {
        console.log("it‘s" + result)
     }
 
 
     [err, result] = await to(taskPromise("fail"))
     if (err) {
        console.log("it‘s error")
     } else {
        console.log("it‘s" + result)
     }
}
 
  asyncTasks()   //it‘ssuccess it‘s error
 

 

 
 
 
 
 
 
 
 
 
 
 
 

以上是关于如何在写await async的时候不用try catch的主要内容,如果未能解决你的问题,请参考以下文章

从不用 try-catch 实现的 async/await 语法说错误处理

从不用 try-catch 实现的 async/await 语法说错误处理

如何优雅地处理Async/Await的异常?

嵌套的 try、catch 和 async、await 请求

promise,async await,try catch的问题整理

Jest/Enzyme 使用 try/catch 中的 async/await 方法测试 React 组件