停止这样使用‘async/await’
最近看到一些开发人员使用这种方法来处理 async/await
错误:
/**
* @param { Promise } promise
* @param { Object= } errorExt - 可以传递给 err 对象的附加信息
* @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 成功,则数组中的第一项为 null 表示没有错误,第二项是原始 Promise 的结果。 如果原始 Promise 失败,则数组的第一项是错误的,第二项是未定义的。 仅此而已。
他们认为它很优雅,并使代码更具可读性。 但我不这么认为,也不建议大家这样用!
我认为这样的封装有点过度设计,在大多数情况下,我们其实不需要。 接下来,我将从两个角度阐述该观点:
1.从设计角度出发
async/await
API 的目的是让开发人员可以像编写同步代码一样编写异步代码。 因此可以使用 try...catch
捕获 async/await
错误。
而这样的函数似乎已经为我们准备好了一切,但是其他刚刚看过你代码的开发者总会有这样的疑问:为什么to函数返回的Promise使用的 await 没有包裹在 try...catch 中?
只有找到原来的to函数定义,理解它的意图,才能知道“啊,原来to函数返回的Promise永远不会被拒绝”。
因此它进一步增加了其他开发人员的理解成本,使熟悉的 async/await
变得不那么“熟悉”。
2.从实用性的角度出发
to 函数的主要用例是当在同一个上下文中有多个 await Promise 时,它们对应的错误处理是不同的。 然后使用这个封装函数对每个错误进行不同的处理,减少 try...catch 的使用。
但是在实际编写中,每个to函数之后,都需要使用if语句来判断是否有错误。 这与使用 try...catch 的意图没有什么不同,都是为了检查错误。
其次,在真实的生产环境中,下一个 Promise 依赖上一个 Promise 的情况并不少见。 但重要的一点是,这两个 Promise 通常是关联函数。 所以在外层使用 try...catch
来统一处理错误是没有问题的。 例如:
最后,在 JavaScript 中,大部分 Promise 场景都在 Input/output 上,比如网络 IO 和文件 IO。 这些IO场景可以在底层封装拦截器,根据错误码统一处理。 例如使用 axios 拦截器:
所以它可能不像预期的那样实用。 也就是说,它可能只用于整个项目的一小部分,并且成本大于收益。
这仅是我的观点,大家怎么看?
相关文章
异步堆栈跟踪:为什么 await 击败了 Promise#then()
发布时间:2023/01/09 浏览次数:71 分类:学无止境
-
与直接使用 promises 相比, async 和 await 不仅可以使开发人员的代码更具可读性它们还可以在 JavaScript 引擎中实现一些有趣的优化! 这篇文章是关于这样一种优化,涉及异步代码的堆栈跟
JavaScript 中 Promise.resolve is not a constructor 错误
发布时间:2022/12/02 浏览次数:212 分类:JavaScript
-
当我们尝试将 Promise.resolve() 方法与 new 运算符一起使用时,会出现Promise.resolve is not a constructor错误。 Promise.resolve() 方法不是构造函数,因此应该在没有 new 运算符的情况下使用它,例如
JavaScript 中如何访问 Promise 的值
发布时间:2022/12/02 浏览次数:75 分类:JavaScript
-
使用 Promise.then() 方法访问承诺的值,例如 p.then(value = console.log(value)) 。 then() 方法接受一个函数,该函数将 promise 的解析值作为参数传递。 // ?️ Example promise const p = Promise . resolve (
JavaScript 中检查函数是否返回 Promise
发布时间:2022/12/02 浏览次数:70 分类:JavaScript
-
要检查函数是否返回 Promise ,请检查函数是否异步或调用它并检查函数是否返回具有函数类型 then 属性的对象。 如果满足任一条件,该函数将返回一个 Promise 。 // ✅ Promise check functio
使用 JavaScript 检查值是否为 Promise
发布时间:2022/12/02 浏览次数:122 分类:JavaScript
-
要检查一个值是否为 promise ,请检查该值的类型是否为对象并且是否具有名为 then 的函数类型的属性,例如 typeof p === object typeof p.then === function 。 如果两个条件都返回 true,则该值是一
如何创建自己的 Promise
发布时间:2022/09/07 浏览次数:144 分类:学无止境
-
有没有想过 Promise 在 JavaScript 中是如何工作的? 让我们实现一个,看看我们是否能更好地理解它。