先说Promise.all
我们都知道Promise.all
的功能,入参是一些promise
(也可以不是),返回跟入参位置一一对应的promise
结果。
那我们有时候也需要处理一批异步任务,返回结果保存在不同字段中,我们可能会这样写
const eat = await eatPromise;
const listen = await listenPromise;
return {
eat,
listen
}
我们希望如何?
我们希望有一个Promise.objAll
函数,入参是obj
(值为promise
的键值对),返回一个obj
(值为promise的执行结果
)
实现如下(参考手写Promise.all):
Promise.objAll = (obj) => new Promise((resolve,reject) => {
const keys = Object.keys(obj);
const { length } = keys;
const res = {};
let i = 0;
keys.forEach(key => {
let cur = typeof obj[key] === 'function' ? new Promise(resolve => obj[key](resolve)) : obj[key];
Promise.resolve(cur).then(now => {
res[key] = now;
++i === length && resolve(res);
},reject)
});
})
再搞个函数,防止重复添加
// 扩展promise,使它具备objAll能力
function addObjAll2Promise() {
// 防止重复添加
if (Promise.objAll) {
return;
}
Promise.objAll = (obj) => new Promise((resolve,reject) => {
const keys = Object.keys(obj);
const { length } = keys;
const res = {};
let i = 0;
keys.forEach(key => {
let cur = typeof obj[key] === 'function' ? new Promise(resolve => obj[key](resolve)) : obj[key];
Promise.resolve(cur).then(now => {
res[key] = now;
++i === length && resolve(res);
},reject)
});
})
}
试试
没有Promise.objAll的时候
const ajaxres = await ajax(1);
const pb = await new Promise(getSome);
const res = {
pa:'123',
pb,
ajaxres
}
有了Promise.objArr之后
const res = await Promise.objAll({
pa: '123',
pb: getSome,
ajaxres: ajax(1)
})