相当于BlueBird Promise.props的ES6承诺?

问题描述 投票:5回答:4

我想等一下承诺的地图来完成。 BlueBird有Promise.props来完成这个,但有一个干净的方法在常规的JavaScript中执行此操作吗?我想我可以创建一个包含单词和Promise的新对象,获取这些对象的Promise数组,然后调用Promise.all并将它们放在地图中,但它看起来有点过分。

javascript node.js promise bluebird es6-promise
4个回答
1
投票

如果你正在处理一个Map,它的值是promises(或者是promises和non-promises的组合) - 你希望最终解析的值是Map,并且所有值都已解析

const mapPromise = map => 
    Promise.all(Array.from(map.entries()).map(([key, value]) => Promise.resolve(value).then(value => ({key, value}))))
    .then(results => {
        const ret = new Map();
        results.forEach(({key, value}) => ret.set(key, value));
        return ret;
    });

虽然,我打赌有人有一个更明智的方式来做到这一点,一些新的ES2015 +的东西对我来说仍然是新的:p


0
投票

建议使用像bluebird这样的库。如果你真的想自己这样做,主要的想法是:

  • 解析每个映射值,并将承诺的值与相应的键连接起来
  • 将这些承诺传递给Promise.all
  • 将最终承诺的数组转换回Map

我会使用Array.from的第二个参数,以及一个键/值对数组可以传递给Map构造函数的事实:

Promise.allMap = function(map) {
    return Promise.all( Array.from(map, 
        ([key, promise]) => Promise.resolve(promise).then(value => [key, value])
    ) ).then( results => new Map(results));
}

// Example data
const map = new Map([
    ["Planet", Promise.resolve("Earth")],
    ["Star", Promise.resolve("Sun")],
    ["Galaxy", Promise.resolve("Milky Way")],
    ["Galaxy Group", Promise.resolve("Local Group")]
]);

// Resolve map values
Promise.allMap(map).then( result => console.log([...result]) );
.as-console-wrapper { max-height: 100% !important; top: 0; }

0
投票

以下是一个适用于普通对象的简单实现

makePromiseFromObject({a: Promise.resolve(1)})是一个与{a: 1}一起解决的承诺。

const makePromiseFromObject = (obj) => {
  const keys = Object.keys(obj)
  const values = Object.values(obj)
  return Promise.all(values)
    .then(resolved => {
      const res = {}
      for (let i = 0; i < keys.length; i += 1) res[keys[i]] = resolved[i]
      return res
    })
}

0
投票

如果您使用ramda,您可以这样做:

export const promiseProps: <T>(obj: {[x: string]: Promise<T>}) => Promise<{[x: string]: T}> =
 (obj) => Promise.all(R.values(obj)).then(R.zipObj(R.keys(obj)));
© www.soinside.com 2019 - 2024. All rights reserved.