【问题标题】:Using Promise.all on the entries of a Map()在 Map() 的条目上使用 Promise.all
【发布时间】:2017-08-20 20:00:24
【问题描述】:

我正在为一些键/值对使用 Map

let myMap = new Map()
myMap.set('foo', 'bar')
myMap.set('foo2', 'bar42')

对于每个 Map 条目,我执行一个返回 Promise 的函数。所有这些 Promise 都可以使用 Promise.all 并行执行。

这就是我现在的做法:

let mapPromises = []
myMap.forEach((value, key) => {
  mapPromises.push(MyModel.forge({key, language, value}).save())
})
await Promise.all(mapPromises)

除了将所有函数调用推入一个数组然后触发Promise.all之外,还有另一种(更短?更快?)的方法来实现这一点?

【问题讨论】:

  • Is there a smarter way - 比什么更聪明?你还没有展示你是如何做到的
  • "对于每个 Map 条目,我执行一个函数" - 你不是已经在使用迭代器了吗?
  • 我稍微改写了原始问题。感谢您指出它的缺陷。

标签: javascript ecmascript-6 promise async-await


【解决方案1】:

我能想到的最简单的代码是

await Promise.all(Array.from(myMap, ([key, value]) => 
    MyModel.forge({key, language, value}).save())
);

参见Array#from 文档

【讨论】:

    【解决方案2】:

    是的,使用 forEach 并手动推送到数组几乎总是一个坏主意。

    你可以直接创建array from的地图,在过程中对其进行映射:

    async function processEntry([key, value]) {
        return MyModel.forge({key, value}).save();
    }
    
    (async function() {
        let myMap = new Map()
        myMap.set('foo', 'bar')
        myMap.set('foo2', 'bar42')
    
        const results = await Promise.all(Array.from(myMap, processEntry));
    }());
    

    但如果你想使用迭代器,你也可以这样做

    function* processEntries(map) {
        for (const [key, value] of map)
            yield MyModel.forge({key, value}).save();
    }
    
    (async function() {
        let myMap = new Map()
        myMap.set('foo', 'bar')
        myMap.set('foo2', 'bar42')
    
        const results = await Promise.all(processEntries(myMap));
    }());
    

    【讨论】:

      【解决方案3】:

      您可以使用Array.from() 将 Map 转换为对数组,首先是键,其次是值。然后使用array.map 构造你的promise 数组以提供给Promise.all

      var pairs = Array.from(myMap); // [['foo', 'bar'], ['foo2', 'bar42']]
      

      【讨论】:

      • 如果你打算map数组,只需使用from的第二个参数
      【解决方案4】:

      是的

      const myArr = [...myMap.entries()].map(([key, value]) => {
        return MyModel.forge({key, language, value}).save()
      });
      
      Promise.all(myArr);
      

      【讨论】:

        【解决方案5】:

        您可以像这样在地图上重新定义迭代器:

        myMap[Symbol.iterator] = function* () {
          yield this.get("foo");
          yield this.get("foo2");
        };
        

        之后,您可以将 Map 与 Promise.all() 一起使用:

        let result = await Promise.all(myMap);
        

        【讨论】:

          猜你喜欢
          • 2020-06-24
          • 1970-01-01
          • 1970-01-01
          • 2021-04-11
          • 2020-04-24
          • 1970-01-01
          • 1970-01-01
          • 2022-01-18
          • 2021-02-21
          相关资源
          最近更新 更多