我的情况是使用Promise.all
这样Promise.all({})
代替更标准的Promise.all([])会非常方便。
但这似乎不起作用
Promise.all({a:1,b:2}).then(function(val){
console.log('val:',val);
});
虽然这当然是
Promise.all([1,2,3]).then(function(val){
console.log('val:',val);
});
(我期望Promise.all能够映射Object文字的值,但保持密钥完整。)
但是the MDN docs for Promise似乎表明Promise all适用于任何迭代。据我所知,对象文字{}
是可迭代的。那我错过了什么?
答案 0 :(得分:3)
如果您查看mdn documentation,那么对象没有迭代器符号。
你可以做的是使用工具函数来创建一个可迭代的对象,然后再使用它。
reference to objectEntries source,但是nodejs没有实现Reflect,所以为了将它与节点I一起使用,只需将其更改为使用Object.keys()
function objectEntries(obj) {
let index = 0;
// In ES6, you can use strings or symbols as property keys,
// Reflect.ownKeys() retrieves both
let propKeys = Object.keys(obj);
return {
[Symbol.iterator]() {
return this;
},
next() {
if (index < propKeys.length) {
let key = propKeys[index];
index++;
return { value: [key, obj[key]] };
} else {
return { done: true };
}
}
};
}
答案 1 :(得分:3)
使用Object.values
。适用于Firefox Nightly:
Promise.all(Object.values({a:1,b:2}))
.then(vals => console.log('vals: ' + vals)) // vals: 1,2
.catch(e => console.log(e));
var console = { log: msg => div.innerHTML += msg + "<br>" };
<div id="div"></div>
然后,为了将结果放回到对象中,我们可以创建一个Promise.allParams
函数:
Promise.allParams = o =>
Promise.all(Object.values(o)).then(promises =>
Object.keys(o).reduce((o2, key, i) => (o2[key] = promises[i], o2), {}));
// Demo:
Promise.allParams({a:1,b:2}).then(function(val){
console.log('val: ' + JSON.stringify(val)); // val: {"a":1,"b":2}
});
var console = { log: msg => div.innerHTML += msg + "<br>" };
<div id="div"></div>
答案 2 :(得分:1)
Syntax
Promise.all(iterable);
Parameters
迭代
可迭代对象,例如Array。见iterable。
答案 3 :(得分:1)
这是另一个异步/等待ES6解决方案:
async function allOf(hash = {}) {
const promises = Object.keys(hash).map(async key => ({[key]: await hash[key]}));
const resolved = await Promise.all(promises);
return resolved.reduce((hash, part) => ({...hash, ...part}), {});
}
这会将密钥转换为产生单个元素哈希的Promise。然后最后,我们将数组中的所有哈希组合到单个哈希中。您甚至可以将其压缩为一个单一的行,以牺牲可读性为代价。
async function allOfOneLiner(hash = {}) {
return (await Promise.all(Object.keys(hash).map(async k => ({[k]: await hash[k]})))).reduce((h, p) => ({...h, ...p}), {});
}
答案 4 :(得分:0)
默认情况下,并非所有对象都是可迭代的。您可以通过定义@@iterator
方法使对象可迭代。 @@iterator
是Well-Known Symbol,Symbol.iterator
:
- 规格名称
@@迭代- [[说明]]
&#34; Symbol.iterator&#34;- 价值和目的
返回对象的默认Iterator的方法。由for-of语句的语义调用。
例如,这将使所有对象可迭代(可能不是一个好主意):
Object.prototype[Symbol.iterator] = function*() {
for(let key of Object.keys(this))
yield this[key];
};
然后你就可以使用
了Promise.all({a:1,b:2}).then(function(val){
console.log('val:', val); // [ 1, 2 ]
});
答案 5 :(得分:0)
使用Babel / ES2015,您可以使用Object.keys和map来获取如下值:
const obj = {a:1,b:2};
const vals = Object.keys(obj).map(k=>obj[k]);
Promise.all(vals).then( vals => { console.log('vals', vals) });
答案 6 :(得分:0)
这个功能可以解决问题:
Promise.allAssoc = function(object){
var values = [], keys = [];
for(var key in object){
values.push(object[key]);
keys.push(key);
}
return Promise.all(values).then(function(results){
var out = {};
for(var i=0; i<results.length; i++) out[keys[i]] = results[i];
return out;
});
};
答案 7 :(得分:0)
ES6方式
Promise.hashProperties = async function(object) {
const keys = [];
const values = [];
for (const key in object) {
keys.push(key);
values.push(object[key]);
}
const results = await Promise.all(values);
for (var i=0; i<results.length; i++)
object[keys[i]] = results[i];
return object;
};