这么优雅的捕获错误的方式,源码才十多行

1,177 阅读2分钟

我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

在写项目的过程中,想必有个东西经常能和我们打交道。没错,就是 Promise,它在开发中能被广泛运用到。自从 Promise 被推出以来,它因解决了回调地狱问题而被大范围使用。

如何捕获错误

try catch

那么,关于 Promise 是如何捕获错误的呢?最常见的方式无疑是 try catch 了。大家可以看看如下这段代码:

const res = await sendReaderStoryAction({
      ......
    }).catch(err => {
      const {response} = err || {};
      const msg = response?.data?.msg || response?.data?.message || '服务器错误';
      console.log(msg);
    });

这是我在项目中引入的 try catch,如果一旦抛出错误,这里可以通过 response 来找出是哪种类型的错误,并在后台打印出来。但是,如果在操作比较多的情况下使用 try catch 捕获错误,那么就需要在每一步操作进行 try catch,这样显得非常繁多,不够整洁。那么,我们还有什么方法可以更好的捕获 await 的错误吗?

await to js

这就需要请上我们今天的主角了,await to js。它的源码部分也不复杂,不过十几二十来行,如下代码是 await to jsTS 源码部分

export function to<T, U = Error> (
    promise: Promise<T>,
    errorExt?: object
): Promise<[U, undefined] | [null, T]> {
    return promise
        .then<[null, T]>((data: T) => [null, data])
        .catch<[U, undefined]>((err: U) => {
            if (errorExt) {
                const parsedError = Object.assign({}, err, errorExt);
                return [parsedError, undefined];
            }
            return [err, undefined];
        });
}
export default to;

这里的 T 代表的是成功时返回的数据类型,U 代表错误时返回的类型。我们哪怕没学过 TS,也能看出它在两种情况下返回了两种数组结果 [null, data][err, undefined]。无论成功还是失败都会返回一个数组,数组的第一项是和错误有关,数组的第二项就是和响应结果有关。如果是成功的话数组第一项错误信息为空 null,数组第二项响应结果为正常返回 data;如果是失败的话数组第一项也就是错误信息为错误信息 err,数组第二项也就是响应结果返回 undefined。这就是这个源码部分的逻辑。简单点理解就是成功就会返回 [null, data],失败就会返回 [err]

总结

通过阅读 await to js 的源码,学习到了一种看似更优雅的捕获错误方式,知道了它的原理以及使用方式,它不同于 try catch,它能使代码更加简洁。当然,在项目开发中,用哪种都可,这都是个人习惯。await to js 是个 npm 包,可以下载好后直接在项目引入,这还是比较方便的。