【问题标题】:How do I resolve promises within stream?如何解决流中的承诺?
【发布时间】:2017-01-05 15:28:55
【问题描述】:

我有一个高地流,其中每个元素都是一个获取请求的承诺:

const stream = _[promise1, promise2, promise3, ...];

当然,当我跑步时:

const stream.each(console.log)

我只看到:

Promise { <pending> }
Promise { <pending> }
Promise { <pending> }

但我想创建一个管道并处理承诺的实际结果。 (我不想使用thenawait)。我想通过流管道解决这些承诺。

我想应该有一种方法可以使高地流仅将已解决的 Promise 映射到新流中,因此我希望能够将 Promise 流扁平化为它们的实际值流。

四处挖掘,我想flatMapflatten 应该做我正在寻找的东西,但我不知道如何继续,我所有的试验和错误都失败了。

我试过了:

 stream.flatMap((id: number) => {
     return myAsyncGetRequest(id);
 }).each(console.log)

如何解决流中的承诺?

【问题讨论】:

  • 这似乎与 reahttp://stackoverflow.com/questions/25638527/using-highland-js-to-perform-async-tasks-in-series-with-references-to-original-s 相关

标签: javascript stream promise highland.js


【解决方案1】:

我偶然发现了一个 github 问题,the answer of quarterto 启发了我:

必须在 Highland 中封装 promise 才能让 flatMap 按预期工作:

 stream.flatMap((id: number) => {
     return Highland(myAsyncGetRequest(id));
 }).each(console.log)

该线程还阐明了为什么不等待承诺。

quarterto 表述为:

Highland 不是 Promise 库。它可以像它一样消耗承诺 消费数组、回调和事件发射器,但它的 API 是专注的 围绕转换流式价值,而不是承诺。就像问 为什么 Array.prototype.map 不等待承诺,或者为什么 Bluebird 不等待 Streams。

或者如vqvu所说:

Highland 溪流已经代表了一个未来的值数组,所以它 将 Promise 视为特殊的东西是没有意义的。

【讨论】:

    【解决方案2】:

    Highland 不太适合您的需求,尽管我认为这是可能的。

    看看scramjet,它是一个建立在像 Highland 这样的标准节点流之上的框架,但它基于 Promises,在异步情况下的工作方式与同步情况完全相同。

    以下是您在超燃冲压发动机中兑现承诺的方式:

    const scramjet = require("scramjet");
    
    const stream = scramjet.DataStream.fromArray([d1, d2, d3])
                       .map((data) => aCallThatReturnsAPromise(data))
                       .stringify((resolved) => JSON.stringify(resolved) + "\n")
                       .pipe(fs.createWriteStream('./yourfile.jslines');
    

    由于 Highland 和 Scramjet 都在节点流之上工作,因此您可以根据需要轻松地通过管道连接到之前的管道。而且它没有依赖关系,所以你不会让你的软件重两倍。 :)

    【讨论】:

      猜你喜欢
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-24
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多