在 Ramda 管道中使用 Promise.all

5
Promise.all 在 ramda 管道函数中的使用方式是怎样的?我认为我可能漏掉了些小细节。
const pipeline: Function = R.pipe(
    R.map((record) => record.body),
    R.map(JSON.parse),
    R.map(asyncFunction),
    console.log
);

返回一个 promise 数组(Promise.all 的输入参数)。
[ Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> } ]

但是,如果我尝试使用Promise.all等待这些承诺被解决,就像这样:

const pipeline: Function = R.pipe(
    R.map((record) => record.body),
    R.map(JSON.parse),
    R.map(asyncFunction),
    Promise.all,
    R.andThen(useTheReturn)
);

我最后遇到了一个类型错误,指出我正在尝试将Promise.all作为构造函数类型使用。

{
    "errorType": "TypeError",
    "errorMessage": "#<Object> is not a constructor",
    "stack": [
        "TypeError: #<Object> is not a constructor",
        "    at all (<anonymous>)",
        "    at /var/task/node_modules/ramda/src/internal/_pipe.js:3:14",
        "    at /var/task/node_modules/ramda/src/internal/_arity.js:11:19",
        "    at Runtime.exports.handler (/var/task/lambda/data-pipeline/1-call-summary-ingestion/index.js:14:19)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}
2个回答

6
您需要将Promise.all绑定到Promise
const pipeline: Function = R.pipe(
  R.map((record) => record.body),
  R.map(JSON.parse),
  R.map(asyncFunction),
  R.bind(Promise.all, Promise),
  R.andThen(useTheReturn)
);

演示:

const pipeline = R.pipe(
  R.bind(Promise.all, Promise),
  R.andThen(R.sum)
);

const promise1 = Promise.resolve(10)
const promise2 = 20
const promise3 = new Promise((resolve) => setTimeout(resolve, 100, 30))

const result = pipeline([promise1, promise2, promise3])

result.then(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>


1
抱歉问一个愚蠢的问题,但是为什么Promise.all的上下文在这里切换并且必须显式设置回Promise - Mmm Donuts
“Ah ha” -> https://github.com/ramda/ramda/issues/2521#issuecomment-503549521 “恐怕不会。Promise.all,至少在某些环境中,包括Chrome和Node,不是一个纯函数。我没有看过实现,但我认为它包含一些this引用。” - Mmm Donuts
确实。我只是在写下来,但这比我的描述更好 :) - Ori Drori
实际上,使用 R.andThen(console.log) 函数仍然返回一个挂起的 Promise (非常奇怪)。 - Mmm Donuts
1
R.andThen 返回一个 Promise,该 Promise 包含回调函数生成的值,在 console.log 的情况下该值为 undefined - Ori Drori
显示剩余3条评论

-1

我写了一个叫做rubico的库,它使得这个过程更简单,因为你不需要担心绑定Promise或者自己使用Promise.all。

import { pipe, map } from 'rubico'

const pipeline: Function = pipe([
  map((record) => record.body),
  map(JSON.parse),
  map(asyncFunction),
  console.log,
]);

pipe类似于Ramda的管道,它将函数链接在一起,但在异步函数的情况下,它会在将值传递给下一个函数之前解析返回的Promise。

map类似于Ramda的map,但它只适用于异步函数。


8
我已经为这个答案添加了一份免责声明,明确说明你是推荐的库的作者。根据帮助中心的要求,此披露是必需的,以避免被视为垃圾邮件发送者。另外,我不确定为什么你要编辑并删除这个答案中的所有上下文解释,这反而使它变得更糟糕了,所以我也将其回滚了。此外,因为这似乎涉及到一个个人开源项目,你可能还想阅读这篇文章:[* 如何提供个人开源库? *] (https://meta.stackexchange.com/q/229085)。 - Cody Gray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接