本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
对于promise错误的捕获,一般常用两种方式,一是使用promise自带的.catch()获,但是这种捕获方式,还是以链式的形式来编写代码。另一种方式就是使用try...catch来进行错误的捕获,这种方式更加的常用,但是会使得代码整体看上去不够简洁,那么如何优雅的捕获错误呢?那可以看看await-to-js是如何工作的!
准备工作
- 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
-
参数promise表示传入的promise对象,传入的promise对象应当是resolve或者reject状态,否则将会报错.
-
可选参数errorExt表示传入的错误文本对象,未传入时,返回promise.catch捕获到的错误信息,传入时,则会将promise捕获到的错误信息与传入的错误文本信息进行合并,然后再返回。
-
返回值以数组[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时,还需要注意这一点。
总结
- 了解了await-to-js这个工具库,今后可以将它用在项目当中。
- 加深了对Object.assign()的理解,了解了for...in如何遍历字符串。