我正在处理一个数据流,通常来自RxNode.fromReadableStream()
,其中有一个异步的中间步骤,并且只能以某种并发运行,同时输出步骤只能运行串行,分散批次。
基本上是一个经典的转换管道:
cat file | parallel -P5 transform | xargs -n1000 process
承诺它会像(非常简化):
lines.on('readable', function read() {
let line;
while (line = lines.read()) {
queue.push(line);
if (queue.length >= 10) {
return Promise.map(queue, item => someAsyncTransformations(item), {concurrency: 5})
.then(items => someFinalAsyncProcessing(items))
.then(read);
}
}
});
通过在变换后插入控制器,我可以确保变换独立执行,给我流水线操作;推迟和合并的结合似乎让我控制了异步性和并发性。
但是,我正在使用controlled()
来确保地图步骤有效地暂停处理直到完成。它看起来真的很难看 - 是不是有更好的,非手动的方式来实现无损背压?
另外,我相信我必须对变换器使用相同的控制技巧,否则整个流将一次性转换并吹掉内存使用。是否有更惯用的方式?
最后:如果输入的大小不能被批量大小整除,则上述实际上不起作用。出于某种原因,如果我request()
的余数超过剩余项目的数量,整个管道就会退出;甚至没有调用onComplete
。实际上,如果我最初使用大数字调用request()
,整个管道似乎无限期地重复相同的内容。错误或预期的行为?
编辑:我发现我可以使用。没关系。concatMap