如何在Javascript中编写没有try-catch块的async/await

 Promises 使得可以简化异步流程并避免回调地狱。

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

               // do something....
          });
      });
   });
}

async/await 使得可以以编写同步代码的方式处理异步代码。在 async/await 函数中,通常使用 try/catch 块来捕获错误,防止程序中断。

但是如果存在多个 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);
}

 如何解决呢?

我们可以利用 Promise 的特性,分别在 promise.thenpromise.catch 中返回不同的数组,其中 fulfilled 的时候返回数组第一项为结果,第二个是 nullrejected 的时候,返回数组第一项为 null,第二项为错误信息。使用的时候,判断第二项是否为空,即可知道是否有错误。

/**
 * @param { Promise } promise
 * @param { Object= } errorExt - 传递给 err 对象的附加信息
 * @return { Promise }
 */
function to<T, U = Error> (
  promise: Promise<T>,
  errorExt?: object
): Promise<[null, U] | [T, null]> {
  return promise
    .then<[T, null]>((data: T) => [data, null])
    .catch<[null, U]>((err: U) => {
      if (errorExt) {
        const parsedError = { ...err, ...errorExt });
        return [null, parsedError];
      }

      return [null, err];
    });
}

或者可以在try...catch 中执行 promise ,以处理错误,最后将返回一个长度为2的数组,其中第一个是 response 或 result ,第二个则是 error。

async function asyncHandler<T, U = Error>(
  prom: Promise<T>
): Promise<[T | null, U | null]> {
  try {
    return [await prom, null];
  } catch (error) {
    return [null, error];
  }
}

/** 同步函数处理 */
function syncHandler<T extends any[], K, U = Error>(
  func: (...args: T) => K,
  ...params: T
): [K | null, U | null] {
  try {
    return [func(...params), null];
  } catch (error) {
    return [null, error];
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值