Javascript Promise.all位于带有FP的promises的对象数组上

Javascript Promise.all位于带有FP的promises的对象数组上,javascript,node.js,functional-programming,ramda.js,Javascript,Node.js,Functional Programming,Ramda.js,因此,我使用NodeJS和Ramda,我有一个对象数组,如: [ { x: 'abc', y: [] }, { x: '123', y: [1, 2, 3] } ] 然后我想在返回承诺的请求中使用x,结果是(使用over和lensProp来自Ramda): [ { x:我保证, y:[] }, { x:我保证, y:[1,2,3] } ] 现在我想将最后一个数组转换为: Promise<[

因此,我使用NodeJS和Ramda,我有一个对象数组,如:

[
    {
        x: 'abc',
        y: []
    },
    {
        x: '123',
        y: [1, 2, 3]
    }
]
然后我想在返回承诺的请求中使用
x
,结果是(使用
over
lensProp
来自Ramda):

[
{
x:我保证,
y:[]
},
{
x:我保证,
y:[1,2,3]
}
]
现在我想将最后一个数组转换为:

Promise<[
    {
        x: String,
        y: []
    },
    {
        x: String,
        y: [1, 2, 3]
    }
]>
承诺
我如何以函数式的方式实现这一点(比如在函数式编程中,而不是在一些只起作用的东西中=])


我能想到的最好办法是从
x
获得所有承诺,使用
Promise.all
并使用
然后
zip
将结果与
y
s一起返回。但我不接受这一解决方案。

一个选项是引入一个新的助手函数,其行为类似于
R.traverse
,专门用于承诺,并将处理对象的特定属性。让我们称之为
traversePropP

// traversePropP :: (a -> Promise b) -> String -> {a|...} -> Promise {b|...}
const traversePropP = R.curry((toPromiseFn, prop, obj) =>
  toPromiseFn(obj[prop]).then(v => R.assoc(prop, v, obj)))
这可以有效地让您从对象的指定属性生成承诺,用创建的承诺解析的最终值替换该属性

然后,您可以使用此新函数映射数组中的所有对象,然后将生成的承诺数组传递给
Promise.all

const traversePropP=R.curry((toPromiseFn,prop,obj)=>
toPromiseFn(obj[prop])。然后(v=>R.assoc(prop,v,obj)))
//延迟值的示例Promise生成函数
常数delayP=n=>x=>
新承诺((res,rej)=>setTimeout(()=>res(x,n))
常数fn=R.管道(
R.map(traversePropP(delayP(500),'x')),
x=>Promise.all(x)
)
常数数据=[
{
x:‘abc’,
y:[]
},
{
x:'123',
y:[1,2,3]
}
]
console.log('begin')
fn(data).then(x=>console.log('result:',x))

这里有一个干净的方法来做你想做的事

从'rubico'导入{pipe,assign,map,get}
const makeRequest=async x=>{/*…*/}
常数数据=[
{x:'abc',y:[]},
{x:'123',y:[1,2,3]},
]
地图(分配)({
x:pipe([get('x'),makeRequest]),
}))(数据)
最后的输出是一个对象数组的承诺,该数组的
x
属性被请求的结果覆盖

promise.all(array.map({x,y})=>x.then(x=>({x,y})))
// traversePropP :: (a -> Promise b) -> String -> {a|...} -> Promise {b|...}
const traversePropP = R.curry((toPromiseFn, prop, obj) =>
  toPromiseFn(obj[prop]).then(v => R.assoc(prop, v, obj)))