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

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 这样看的话异步可以像同步那样处理很简洁易读,但是错误的捕获却做不到,这里需要用到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
 

 

  参考:https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/                      
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄