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

Javascript 相当于ES6承诺的BlueBird Promise.props?,javascript,node.js,promise,bluebird,es6-promise,Javascript,Node.js,Promise,Bluebird,Es6 Promise,我想等待世界地图的承诺完成。BlueBird有Promise.props来实现这一点,但是在常规javascript中有没有干净的方法来实现这一点?我想我可以制作一个包含单词和承诺的新对象,获得这些对象的一系列承诺,然后调用Promise.all并将它们放在地图上,但这似乎有些过分 如果您处理的值是承诺(或承诺和非承诺的混合)-并且希望最终解析的值是所有值都已解析的映射 const mapPromise = map => Promise.all(Array.from(map.en

我想等待世界地图的承诺完成。BlueBird有Promise.props来实现这一点,但是在常规javascript中有没有干净的方法来实现这一点?我想我可以制作一个包含单词和承诺的新对象,获得这些对象的一系列承诺,然后调用Promise.all并将它们放在地图上,但这似乎有些过分

如果您处理的值是承诺(或承诺和非承诺的混合)-并且希望最终解析的值是所有值都已解析的
映射

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

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

  • 解析每个映射值,并将承诺值与相应的密钥连接回来
  • 将这些承诺传递给
    Promise.all
  • 将最终承诺的数组转换回映射
我将使用
Array.from
的第二个参数,以及可以将键/值对数组传递给
Map
构造函数的事实:

Promise.allMap=函数(map){
返回Promise.all(数组)from(映射,
([key,promise])=>promise.resolve(promise)。然后(value=>[key,value])
))。然后(结果=>新地图(结果));
}
//示例数据
常量映射=新映射([
[“行星”,承诺。解决(“地球”)],
[“星”,承诺。解决(“太阳”)],
[“银河”,承诺。解决(“银河”)],
[“银河集团”,Promise.resolve(“本地集团”)]
]);
//解析映射值
然后(result=>console.log([…result])

.as控制台包装{max height:100%!important;top:0;}
在普通对象上工作的Bluebird.props实现:

/**
*此函数将“{a:somePromise}”映射为
*用“{a:resolvedValue}”解析。
*@param{object}obj
*@returns{Promise}
*/
函数makePromiseFromObject(obj){
常量键=对象键(obj);
常量值=对象值(obj);
返回承诺。全部(值)
。然后(已解决=>{
常数res={};
for(设i=0;i
如果您使用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)));
export const promiseProps:(obj:{[x:string]:Promise})=>Promise=
(obj)=>Promise.all(R.values(obj))。然后(R.zipObj(R.keys(obj));

您只需使用Promise.all+reduce编写即可

const promiseProps = (props) => Promise.all(Object.values(props)).then(
      (values) => Object.keys(props).reduce((acc, prop, index) => {
         acc[prop] = values[index];
         return acc;
      }, {})
    );
古老的图书馆有一个承诺的对应物:

推荐的
async-q
库支持
async
库中的所有函数。特别是
async.parallel()
。乍一看,
async.parallel()
在接受函数数组(注意一个区别,函数数组,而不是承诺)并并行运行时,看起来就像
Promise.all()
async.parallel
的特殊之处在于它还接受一个对象:

const asyncq = require('async-q');

async function foo () {
    const results = await asyncq.parallel({
        something: asyncFunction,
        somethingElse: () => anotherAsyncFunction('some argument')
    });

    console.log(results.something);
    console.log(results.somethingElse);
}

结合ES6+Object.entries()和Object.fromEntries()的替代实现:


为了简单js对象的完整性,还有一个很好的lodash变体

async function makePromiseFromObject(obj: {[key: string]: Promise<any>}) {
    return _.zipObject(Object.keys(obj), await Promise.all(Object.values(obj)))
}    
异步函数makePromiseFromObject(obj:{[key:string]:Promise}){
return u.zipObject(Object.keys(obj),wait Promise.all(Object.values(obj)))
}    

我有两种使用ES6异步函数的不同实现:

异步函数PromiseAllProps(对象){
const values=wait Promise.all(Object.values(Object));
Object.keys(Object.forEach((key,i)=>Object[key]=values[i]);
返回对象;
}
一行较短,但优化程度较低:

异步函数PromiseAllProps(对象){
const values=wait Promise.all(Object.values(Object));
返回Object.fromEntries(Object.keys(Object.map)((prop,i)=>([prop,values[i]]);
}
例子
const info=wait PromiseAllProps({
名称:fetch('/name'),
电话:获取('/phone'),
text:fetch('/foo'),
});
控制台日志(信息);
{
姓名:“约翰·阿普尔赛德”,
电话:"5551234",,
文字:“你好,世界”
}

我想你的
地图
有承诺的价值吗?如果我正确理解了这个问题,
Promise.all(map.values())
?如果这是错误的,你能至少展示你正在处理的“对象”以及它是如何“创建”的吗?向我们展示你开始使用的代码(比如可能是具有承诺属性的对象),并解释你试图实现的目标。如果没有一些细节,我们无法在任何具体方面帮助您。“单词”是什么意思?“单词”只是一个字符串。如果我等待Promise.all(map.values()),下一个“then()”将只能访问值,而不能访问键。如果我错了,请纠正我如果你同意将该映射转换为常规对象,你可以使用
async-q
library它本身不是内置的,但是如果OP的意图是避免添加库,那么这是最好的答案(IMO)OP的意图是以一种干净的方式(参见纯js)完成它,而不依赖于其他库
async function makePromiseFromObject(obj: {[key: string]: Promise<any>}) {
    return _.zipObject(Object.keys(obj), await Promise.all(Object.values(obj)))
}