【若川视野 x 源码共读】第21期 | await-to-js 如何优雅的捕获 await 的错误

176 阅读2分钟

本文参加了由公众号@若川视野 发起的每周源码共读活动,点击了解详情一起参与。

学习目标

await-to-js 使用和原理

源码地址

github.com/scopsy/awai…

博客地址

使用

// 安装
npm i await-to-js --save

// 使用
import to from 'await-to-js';

// 普通函数使用会直接报错
const test0 = () => {
    return 10
}
const func = async () => {
  const [ err, data ] = await to(test0());
  console.log(err, data)
}
func()

// async定义的函数返回的是promise 
const test1 = async () => {
  return 100 // 相当于Promise.resolve(100)
}
const test2 = async () => {
  throw 'custom-error' // 相当于Promise.reject('custom-error')
}

const func1 = async () => {
  const [ err1, data1 ] = await to(test1());
  console.log(err1, data1)
  const [ err2, data2 ] = await to(test2());
  console.log(err2, data2)
}
func1()

// null 100
// custom-error undefined

使用时需要注意: to函数的参数必须是promise, 否则会报错

源码解读

安装依赖并编译为js

npm i
npm run build

以下为编译后的代码(对,你没看错,就这几行),主要功能就是包装promise,返回错误信息promise的结果,从而代替try{}catch(){}优雅的捕获await的错误

function to(promise, errorExt) {
    return promise
        .then(function (data) { return [null, data]; })
        .catch(function (err) {
        if (errorExt) {
            var parsedError = Object.assign({}, err, errorExt);
            return [parsedError, undefined];
        }
        return [err, undefined];
    });
}

从源码可以得知:

  • 入参有两个(promise, errExt),第一个是promise,第二个是自定义的错误对象,发生错误时会合并到错误对象返回
  • 返回值为数组形式,第一个是错误对象(默认返回null),第二个是正常返回值(默认返回undefined
  • 通过then方法来添加回调并return Promise结果
  • 利用Promise的错误冒泡,通过catch捕获错误并return 结果

扩展

  • 虽然nodejs支持99%的ES6特性,但是采用的仍然是Commonjs模块系统,当需要命令行运行带有ES modlue的文件时,则需要babel的支持。步骤如下:
npm install babel-cli -g

npm install babel-preset-env -D

babel-node --presets env examples.js
  • 当TS书写的npm包需要生成文档时,可以使用typedoc自动生成

总结

平时书写代码要追求优雅。 这个await-to-js做到了既简单又好用,优雅地解决了错误捕获问题。回到我们自己,却想不到这样去解决问题。所以,以后遇到不顺眼的代码,要多思考,多改造,多尝试,找到更优雅的处理方式。