对象字面量(散列)与Promise.all

我有一种使用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映射对象文字的值,但保持键不变。)

但MDN文件的承诺似乎表明,承诺所有将工作任何迭代。 就我所知,一个对象字面{}是一个可迭代的。 那么我错过了什么?

如果您查看这些mdn文档 ,对象没有Iterator符号。

你可以做的是使用工具函数来创build一个可迭代的对象,然后消耗它。

引用objectEntries源 ,但是nodejs没有实现Reflect,所以为了与节点一起使用它,只需将其改为使用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 }; } } }; } 

使用Object.values 。 适用于Firefox每晚:

 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> 
 Syntax Promise.all(iterable); Parameters 

迭代

一个可迭代的对象,比如一个Array。 看到迭代。

并不是所有的对象都是默认可迭代的。 您可以通过定义@@iterator方法来使对象可@@iterator@@iteratorSymbol.iterator 的一个已知符号 :

  • 规格名称
    @@迭代器
  • [[描述]]
    “Symbol.iterator”
  • 价值和目的
    返回对象的默认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 ] }); 

使用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) }); 

这个函数有诀窍:

 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; }); };