【第21期】| await-to-js 如何优雅的捕获 await 的错误

129 阅读3分钟

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

对于promise错误的捕获,一般常用两种方式,一是使用promise自带的.catch()获,但是这种捕获方式,还是以链式的形式来编写代码。另一种方式就是使用try...catch来进行错误的捕获,这种方式更加的常用,但是会使得代码整体看上去不够简洁,那么如何优雅的捕获错误呢?那可以看看await-to-js是如何工作的!

准备工作

  1. git地址
1.clone代码 git clone https://github.com/scopsy/await-to-js 

2.安装依赖 npm i 

3.打包 npm run build (源码是用ts写的,打包后js版本会出现在compiled目录下)

源码分析

/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
export 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];
    });
}
export default to;
//# sourceMappingURL=await-to-js.js.map
  1. 参数promise表示传入的promise对象,传入的promise对象应当是resolve或者reject状态,否则将会报错.

  2. 可选参数errorExt表示传入的错误文本对象,未传入时,返回promise.catch捕获到的错误信息,传入时,则会将promise捕获到的错误信息与传入的错误文本信息进行合并,然后再返回。

  3. 返回值以数组[err,data]的形式,err为null时,表示未发生错误,data为undefined时,表示发生错误,错误信息为err或者捕获到的错误与错误文本对象合并后的parsedError。

代码测试

async function test(){
    const p1 = new Promise((resolve)=>{resolve('fulfiled')})
    const p2 = Promise.reject('rejected')
    const p3 = Promise.reject({error:'fulfiled'})
    
    const [err1,data1] = await to(p1)
    const [err2,data2] = await to(p2)
    const [err3,data3] = await to(p3,{errorExt:'Error'})

    console.log(err1,data1) // null       fulfiled
    console.log(err2,data2) // rejected  undefined 
    console.log(err3,data3) // { error: 'fulfiled', errorExt: 'Error' }   undefined 
}

在测试的过程中,发现当reject被捕获到的err为字符串,且有errorExt对象进行传入时,在与errorExt进行合并的时候,将会把字符串进行遍历,索引值为key,索引对应位置的值为value,如下:

   const p4 = Promise.reject('err')
   const [err4,data4] = await to(p4,{errorExt:'Error'})
   console.log(err4,data4) // { '0': 'e', '1': 'r', '2': 'r', errorExt: 'Error' }    undefined 

思考:

这里又是使用了Object.assign()的方法进行捕获到的错误与错误文本对象的合并,那么这里展示Object.assign()的源码:

var _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
        //遍历一个对象的自身和继承来的属性,
        //常常配合hasOwnProperty筛选出对象自身的属性
        for (var key in source) {  
            //使用call方法,避免原型对象扩展带来的干扰
            if (Object.prototype.hasOwnProperty.call(source, key)) {
                target[key] = source[key];
            }
        }
    }
    return target;
};

这里可以看到,Object.assign()是使用了for...in的遍历方式来遍历对象属性,reject()一个字符串时,才会给解析成{ '0': 'e', '1': 'r', '2': 'r'}的形式(for...of一样)。所以在使用await-to-js时,还需要注意这一点。

总结

  1. 了解了await-to-js这个工具库,今后可以将它用在项目当中。
  2. 加深了对Object.assign()的理解,了解了for...in如何遍历字符串。