使用 Ramda 拒绝承诺

Using Ramda reject with Promises

Ramda.reject() 如何与 Promises 一起使用?

map()可以这样工作

const data = [ {id: 1}, {id: 2} ]
const userIsAdmin = (user) => isAdmin(user) // async database call
const result = await Promise.all(R.map(userIsAdmin, data))
console.log(result) // [true, false]

但我真正想要的是找回用户 ID,但管理员拒绝了。我使用 pipeP.

尝试了以下代码和其他变体
await Promise.all(R.reject(async (d) => await userIsAdmin(d))(data))

如何做到这一点?

另一种方法是重构 isAdmin() 以接受数组并等待一个承诺完成。

我不确定我是否完全遵循,但是你能不能简单地在 Promise.all 的结果上使用 reject

const result = await Promise.all(R.map(asyncFn, data))
console.log(result) //=> [true, false]
console.log(R.filter(R.identity, result)) //=> [true]

但也许有些混乱。您确实想使用 reject 来实现它的目的,对吗?它只是 filter 的变体,谓词颠倒了,即 (fn, list) => R.filter(R.complement(fn), list) 的(柯里化)等价物。它与提供给 Promise 构造函数中给定回调的 reject 函数无关。

更新

对于更新后的问题,我认为最简单的方法仍然是对 Promise.all 调用的结果使用 reject,但您可能必须将其与原始数据结合起来。类似于:

const removeAdmins = pipe(zip, reject(head), pluck(1))
removeAdmins(result, data)

zip 将两个(等长)列表组合成对。然后在对上调用 head 返回布尔值,因此 reject(head) 过滤掉那些从 Promise.all 调用中返回 true 的值。然后 pluck(1) returns 来自每个剩余对的第二个元素(原始对象)。

那会如你所愿吗?