停止像这样使用 “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


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


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


目录
相关文章
|
6月前
|
JavaScript 前端开发
js开发:请解释什么是ES6的async/await,以及它如何解决回调地狱问题。
ES6的async/await是基于Promise的异步编程工具,简化了代码并提高可读性。它避免回调地狱,将异步操作转化为Promise,使得代码同步化。错误处理更直观,无需嵌套回调或.then()。
50 1
|
前端开发 JavaScript
前端 fetchMetadata: sill fetchPackageMetaData error for detec卡住解决办法
前端 fetchMetadata: sill fetchPackageMetaData error for detec卡住解决办法
2164 0
|
3天前
|
JavaScript 前端开发 开发者
async/await和Generators在处理异步时有什么区别
总的来说,async/await 是在 Generators 的基础上发展而来的,它解决了 Generators 在处理异步时的一些不足之处,提供了更简洁、高效和易于理解的方式来处理异步操作。然而,Generators 在某些特定场景下仍然可能有其应用价值。
20 4
|
3月前
【Azure Function】在Function执行中遇见Timeout错误
【Azure Function】在Function执行中遇见Timeout错误
|
6月前
|
C#
C#学习系列相关之多线程(四)----async和await的用法
C#学习系列相关之多线程(四)----async和await的用法
|
vr&ar Swift
大师学SwiftUI第9章Part 1 - 异步并发之Task、Async、Await和错误
苹果系统借助现代处理器的多核可同步执行多条代码,提升同一时间内程序所能执行的任务。例如,一段代码从网上下载文件,另一段代码可以在屏幕上显示进度。此时,我们不能等待第一个执行完后再执行第二个,而必须要同步执行这两个任务。
177 0
|
前端开发 JavaScript 数据可视化
javascript逐行显示数据及php实时输出前端内容后台保持继续运行的解决方案(setTimeout定时器、flush和ob_flush函数、安装进度展示)
javascript逐行显示数据及php实时输出前端内容后台保持继续运行的解决方案(setTimeout定时器、flush和ob_flush函数、安装进度展示)
200 0
|
前端开发 JavaScript
ajax方法执行同步的黄色警告:Synchronous XMLHttpRequest on the main thread is deprecated的解决方案
ajax方法执行同步的黄色警告:Synchronous XMLHttpRequest on the main thread is deprecated的解决方案
256 0
|
存储 开发工具 数据安全/隐私保护
乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。
众所周知,异步并发编程可以帮助程序更好地处理阻塞操作,比如网络 IO 操作或文件 IO 操作,避免因等待这些操作完成而导致程序卡住的情况。云存储文件传输场景正好包含网络 IO 操作和文件 IO 操作,比如业内相对著名的七牛云存储,官方sdk的默认阻塞传输模式虽然差强人意,但未免有些循规蹈矩,不够锐意创新。在全球同性交友网站Github上找了一圈,也没有找到异步版本,那么本次我们来自己动手将同步阻塞版本改造为异步非阻塞版本,并上传至Python官方库。
乾坤大挪移,如何将同步阻塞(sync)三方库包转换为异步非阻塞(async)模式?Python3.10实现。
|
缓存 JavaScript 前端开发
学习 async,defer 和动态脚本,本文就够了!
学习 async,defer 和动态脚本,本文就够了!
176 0
学习 async,defer 和动态脚本,本文就够了!