最近我看到一些开发者使用这种方法来处理 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
来包装?
所以它可能并不像预期的那样实用。也就是说,它可能只用于整个项目的一小部分,而且成本超过了收益。
这就是我所有的观点,你怎么看?你赞成这种做法吗?
译者: