停止像这样使用 “async/await“,改用原版

简介: 停止像这样使用 “async/await“,改用原版

最近我看到一些开发者使用这种方法来处理 async/await 错误


/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
function to(promise, errorExt) {
  return promise
    .then((data) => [null, data])
    .catch((err) => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt);
        return [parsedError, undefined];
      }
      return [err, undefined];
    });
}
async function doSomething() {
  const [error1, result1] = await to(fetch(''));
  if (error1) {
    return;
  }
  const [error2, result2] = await to(fetch(result1));
  if (error2) {
    return;
  }
  // ...
}


正如你所看到的,他们把函数包起来,把原来的Promise转换成一个肯定会成功的 “Promise”,并返回一个数组。


如果原始的Promise成功了,那么数组中的第一项是空的,表示没有错误,第二项是原始 Promise的结果。如果原来的Promise失败了,那么数组的第一项是错误,第二项是未定义。就是这样了。


他们认为这很优雅,使代码更易读。但我不这么认为,我也不建议这样使用它


我认为这样的封装有点过度,在大多数情况下,不需要这样做。接下来,我将从两个角度说明我的观点。


1. 从设计的角度来看


Async/await API的目的是允许开发者像写同步代码一样写异步代码。因此,可以使用try…catch来捕获async/await错误。


而这样的函数似乎为我们考虑到了一切,但其他刚看到你的代码的开发者总会有这样的疑问。为什么to函数返回的Promise所使用的await没有用try…catch来包装?


111.png


只有找到原始的to函数定义,并理解其意图,你才能知道 “啊,原来to函数返回的 Promise 永远不会被拒绝”。


所以它进一步增加了其他开发者的理解成本,使得熟悉的 async/await 变得不再 “熟悉”。


2. 从实用性的角度来看


to函数的主要使用情况是,在同一上下文中有多个await promises,而它们相应的错误处理方式是不同的。那么就使用这个封装函数对每个错误进行不同的处理,减少对try…catch的使用。


但在实际开发,在每个到函数之后,你需要使用if语句来确定是否有错误。这与使用try…catch的本意没有什么不同,都是为了检查错误。


222.png


其次,在真实的生产环境中,下一个Promise依赖上一个Promise的情况并不少见。但重要的一点是,这两个Promise通常是关联函数。所以在外层使用try…catch来统一处理错误是没有问题的。比如说


333.png


最后,在JavaScript中,大多数Promise场景都是在 Input/output上,比如网络IO和文件IO。这些IO场景可以将拦截器封装在下层,并根据错误代码统一处理。例如,使用axios拦截器。


444.png


所以它可能并不像预期的那样实用。也就是说,它可能只用于整个项目的一小部分,而且成本超过了收益。


这就是我所有的观点,你怎么看?你赞成这种做法吗?


目录
相关文章
|
前端开发
css_字体混合正片叠底与发光
css_字体混合正片叠底与发光
149 0
css_字体混合正片叠底与发光
|
搜索推荐 C#
C#实现冒泡排序算法
C#实现冒泡排序算法
160 0
|
人工智能 算法 图形学
Unity 动画系统基本概念
Unity 动画系统基本概念
290 0
|
存储 算法 C#
C# | 二分查找算法的实现
二分查找法一种在**有序数组**中查找目标值的算法。划重点——“**有序**”,与需要遍历整个数组的查询算法不同,二分查找法通过将数组分成两部分来快速定位目标值所在的位置。 它的主要好处在于它的效率很高。因为它能够通过每次排除一半的元素来快速缩小搜索范围,因此在大型数据集上使用二分查找法可以显著提高查找速度。
230 0
|
搜索推荐 C#
C#冒泡排序算法
C#冒泡排序算法
207 0
C#冒泡排序算法
|
前端开发 图形学 异构计算
Unity优化之Drawcall
Unity优化之Drawcall
1214 0
|
存储 缓存 编解码
项目优化之优化技巧进阶(Unity3D)(一)
做游戏经验比较丰富的人都知道,优化的好坏一直是一个游戏的评判标准之一,它直接影响着玩家们的游戏体验,优化一直是项目中开发周期比较长的一个点,也是开发者头疼的一个问题,要求掌握的知识点比较全面,经验也要求比较丰富。 这篇文章参考很多文章的知识点,加以总结与学习,从最基础的概念讲起,配合讲解各种优化技巧,希望大家可以在我的文章中学到一些东西。
|
机器学习/深度学习 人工智能
Lua 协程coroutine
  协程和一般多线程的区别是,一般多线程由系统决定该哪个线程执行,是抢占式的,而协程是由每个线程自己决定自己什么时候不执行,并把执行权主动交给下一个线程。 协程是用户空间线程,操作系统其存在一无所知,所以需要用户自己去做调度,用来执行协作式多任务非常合适。
1654 0
Lua 协程coroutine
|
C# 索引 算法
【 C# 】(一) ------------- 泛型带头节点的单链表,双向链表实现
在编程领域,数据结构与算法向来都是提升编程能力的重点。而一般常见的数据结构是链表,栈,队列,树等。事实上C#也已经封装好了这些数据结构,在头文件 System.Collections.Generic 中,直接创建并调用其成员方法就行。
1269 0

热门文章

最新文章