美文网首页
在没有try-catch块的情况下编写async await

在没有try-catch块的情况下编写async await

作者: 微志异 | 来源:发表于2019-02-21 09:31 被阅读0次

ES7 Async/await允许开发人员编写看起来是同步的异步JS代码。在此之前ES6中引入Promises,这使得我们简化Async流,并避免了回调地狱。

回调地狱是一个术语,用于描述JS中的以下情况:

function AsyncTask() {

   asyncFuncA(function(err, resultA){
      if(err) return cb(err);

      asyncFuncB(function(err, resultB){
         if(err) return cb(err);
          asyncFuncC(function(err, resultC){
               if(err) return cb(err);
               // And so it goes....
          });
      });
   });

}

这使得难以维护代码和管理控制流非常困难。

Promises出现

ES6中引入了Promises,可以将以前的代码噩梦简化为:

function asyncTask(cb) {
   asyncFuncA.then(AsyncFuncB)
      .then(AsyncFuncC)
      .then(AsyncFuncD)
      .then(data => cb(null, data)
      .catch(err => cb(err));
}

但在实际场景中,Async流可能会变得有些复杂。

ES7 Async/await

注意:需要使用转换器才能享受Async/await,您可以使用babel或typescript来填充所需的polyfill。

它允许你编写这样的代码:

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

}

上面的代码看起来更清晰,但是,错误处理呢?

在async/await函数中,通常使用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);

}

有没有更简洁的解决方案呢?

// to.js
export default function to(promise) {
   return promise.then(data => {
      return [null, data];
   })
   .catch(err => [err]);
}

函数接收一个promise,然后使用返回数据作为第二项解析对数组的成功响应。并且从第一个接收到的错误。

然后我们可以使异步代码看起来像这样:

import to from './to.js';

async function asyncTask(cb) {
     let err, user, savedTask;
     
     [err, user] = await to(UserModel.findById(1));
     if(!user) return cb('No user found');
     
     [err, savedTask] = await to(TaskModel({userId: user.id, name: 'Demo Task'}));
     if(err) return cb('Error occurred while saving task');
     
    if(user.notificationsEnabled) {
       const [err] = await to(NotificationService.sendNotification(user.id, 'Task Created'));  
       if(err) return cb('Error while sending notification');
    }
    cb(null, savedTask);
}

上面的例子只是解决方案的一个简单用例,你可以在to.js方法中附加拦截器,该方法将接收原始错误对象,记录它或者在传回之前做任何你需要做的事情。

我们为这个库创建了一个简单的NPM包await-to-js,你可以使用它来安装它:

npm i await-to-js

来源:https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/

相关文章

  • 在没有try-catch块的情况下编写async await

    ES7 Async/await允许开发人员编写看起来是同步的异步JS代码。在此之前ES6中引入Promises,这...

  • Async/Await VS Promise

    Async/Await VS Promise Async/await 是一种编写异步代码的新方法。之前异步代码的方...

  • 002 Rust异步编程,async await简单介绍

    此节对async/await做简单介绍,旨在让大家有一个简单的认识。 作用 async/.await是Rust编写...

  • async.await

    async/await的错误处理有很多方法来处理错误。 方法1:在函数中使用try-catch 方法2:catch...

  • ES6中的好东西

    1 Await/Async 前端的回调时代我没有赶上,我赶上的是await/async时代。await和async...

  • async和await

    浅谈Async/Await用 async/await 来处理异步 async和await async:声明一个异步...

  • Dart中的异步支持

    文章参考:《Flutter实战》 使用async和await关键字编写异步程序async :用来表示函数是异步的,...

  • async与await

    用 async 和 await 编写现代 JavaScript 异步代码 – JavaScript 完全手册(20...

  • ES2017 async 函数

    async 和 await 在干什么 每个名称都有意义async : 异步await: async wait简...

  • 小程序-云开发

    async和await async:异步(无等待)await:等待(是为了同步) 一、await 关键字只在 as...

网友评论

      本文标题:在没有try-catch块的情况下编写async await

      本文链接:https://www.haomeiwen.com/subject/qbyhyqtx.html