我有一个高地流,其中每个元素都是获取请求的承诺:
const stream = _[promise1, promise2, promise3, ...];
当然,当我跑步时:
const stream.each(console.log)
我只看到:
Promise { <pending> }
Promise { <pending> }
Promise { <pending> }
然而,我想创建一个管道并研究承诺的实际结果。 (我不想使用then
或await
)。我想通过流管道来解决这些承诺。
我想应该有一种方法可以让高地流只将已解决的承诺映射到新的流中,所以我希望能够将一系列承诺压缩成一个实际值的流。
四处搜索,我认为flatMap
或flatten
应该做我正在寻找的事情,但我不知道如何继续进行,我的所有试验和错误都让我失望。
我试过了:
stream.flatMap((id: number) => {
return myAsyncGetRequest(id);
}).each(console.log)
如何解决流中的承诺?
答案 0 :(得分:1)
高地不太适合你的需求,虽然我认为这是可能的。
看看scramjet
,它是建立在像Highland这样的标准节点流之上的框架,但它基于Promises在异步情况下工作的方式与同步方式完全相同的。
以下是您在Scramjet中如何处理您的承诺:
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都在节点流之上工作,因此如果您愿意,可以轻松地管道到之前的管道。它没有依赖性,所以你不会让你的软件重两倍。 :)
答案 1 :(得分:0)
我偶然发现了一个github问题,the answer of quarterto启发了我:
必须在Highland中包含承诺,以便flatMap按预期工作:
stream.flatMap((id: number) => {
return Highland(myAsyncGetRequest(id));
}).each(console.log)
该主题还阐明了为什么不等待承诺。
quarterto将其称为:
Highland不是Promise图书馆。它可以像它一样消耗承诺 使用数组,回调和事件发射器,但其API是重点 转换流量值,而不是承诺。这就像问 为什么Array.prototype.map不等待promises,或为什么Bluebird 不等Streams。
或者如vqvu所述:
高地溪流已经代表了未来的一系列价值观,所以它 将承诺视为特殊事物并没有多大意义。