我可以使用 Node.JS PassThrough 流作为简单的输入缓冲区吗?

问题描述 投票:0回答:1

我正在从 Node.js 运行一个子进程,我们称之为生成器。我需要读取它的输出并处理它。有时,生成器会输出一大块数据,大约 50MB/s。但大多数时候,它产生数据的速度要慢得多。

读取数据的代码有时也会变慢并且读取速度不那么快。总的来说,我的 Node.js 程序读取速度比生成器生成的速度快,但是我这边读取速度和生成器输出速度的这些变化会导致偶尔出现背压,从而减慢生成器速度。

我希望在 Node.js 中缓冲最多约 50MB 的生成器输出。我尝试了这个,但我没有看到太大的改进,而且我不知道如何准确地对此进行基准测试:

/**
 * 
 * @param nodeInputStream
 * @returns {Promise<null>} returns when end of stream is reached
 */
async function readAndProcessStream(nodeInputStream)  {
    // implementation redundant
    return;
}

async function createProcessAndRead() {
    const childArgs = ["arg1", "arg2"];
    const programName = "my_program";
    console.log("Spawn with args: ", programName, childArgs.join(" "));
    const childProc = child_process.spawn(
        programName,
        childArgs,
        {
            stdio:["ignore", "pipe", "ignore"],
            detached: true
        }
    );

    const exitCodePromise = new Promise((resolve, reject) => {
        childProc.once('close', resolve);
    });

    // Try to make a 50MB buffer
    const bufferStream = new PassThrough({emitClose: true, highWaterMark: 50*1024*1024});
    childProc.stdout.pipe(bufferStream);
    await readAndProcessStream(bufferStream);
    // make sure to wait till the process really exists
    await exitCodePromise;
}

上面的代码是否正确地在生成器和处理流的函数之间建立了 50MB 的缓冲区空间?如果不是,正确的做法是什么?

javascript node.js async-await node-streams
1个回答
0
投票

这应该更简单。等到您的

bufferStream
收到
end
事件或
readAndProcessStream
块中是
null
。这意味着您已经处理了子流程的整个输出。无需额外等待子进程完成。

© www.soinside.com 2019 - 2024. All rights reserved.