zoukankan      html  css  js  c++  java
  • 如何在写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
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    第一个ExtJS练习(添加用户面板)
    利用高德地图通过给定坐标点画带箭头方向的路径
    安装myeclipse2015 stable 3.0破解之后发生出现SECURITY ALERT:iNTEGRITY CHECK ERROR然后闪退解决方案
    当你的SSM项目中的springmvc.xml发生第一行错误解决方案
    新建maven项目遇到Select an Archetype时没有maven-archetype-webapp处理方法
    XML、HTML、JSON对比
    Mac配置apache2.4.25服务器
    使用HTTP协议访问网络
    android数据持久化存储
    常用git命令
  • 原文地址:https://www.cnblogs.com/chrissong/p/10841760.html
Copyright © 2011-2022 走看看