node.js - Promise 解析为子流 stdout 并拒绝子流 stderr

标签 node.js process stream promise spawn

我想构建一个使用 require('child_process').spawn 生成子进程的 Promise。该进程将其输出流式传输到 stdout,并将错误流式传输到 stderr

我希望得到以下 promise :

  • reject(child.stderr stream (or it data)) 如果 child.stderr 发出任何数据。
  • resolve(child.stdout stream) 仅当没有发出错误时。

我这样做是因为我想将 promise 链接到:

  • then,用于处理 child.stdout 流(将流上传到 S3 存储桶)。
  • 一个可以处理 child.stderr 流的 catch,让我能够正确处理错误。

像这样组合 promise 和流程流是否可行? 我正在考虑解决标准错误,但不确定如果有大量数据进入标准输出并且我处理速度不够快,那么在标准输出之间会发生什么。

最佳答案

在我看来,问题在于,在整个过程完成之前,您不知道是否在 stderr 上获取过数据,因为它可以随时将数据放在那里。

因此,您必须等待整个过程完成后才能调用 resolve()reject()。而且,如果您希望将整个数据发送到其中任何一个,则必须对它们进行缓冲。您可以在 stderr 上获取数据后立即调用 reject(),但不能保证您拥有所有数据,因为它是一个流。

因此,如果您不想缓冲,最好让调用者直接看到流。

如果您同意缓冲数据,您可以像这样自己缓冲:

基于node.js文档中的spawn示例,您可以像这样添加promise支持:

const spawn = require('child_process').spawn;

function runIt(cmd, args) {
    return new Promise(function(resolve, reject) {
        const ls = spawn(cmd, args);

        // Edit thomas.g: My child process generates binary data so I use buffers instead, see my comments inside the code 
        // Edit thomas.g: let stdoutData = new Buffer(0)
        let stdoutData = "";
        let stderrData= "";
        ls.stdout.on('data', (data) => {
        // Edit thomas.g: stdoutData = Buffer.concat([stdoutData, chunk]);
            stdoutData += data;
        });

        ls.stderr.on('data', (data) => {
            stderrData += data;
        });

        ls.on('close', (code) => {
            if (stderrData){
                reject(stderrData);
            } else {
                resolve(stdoutData);
            }
        });
        ls.on('error', (err) => {
            reject(err);
        });
    }) 
}

//usage
runIt('ls', ['-lh', '/usr']).then(function(stdoutData) {
    // process stdout data here
}, function(err) {
    // process stdError data here or error object (if some other type of error)
});

关于node.js - Promise 解析为子流 stdout 并拒绝子流 stderr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35896006/

相关文章:

node.js - NPM : Cannot find module 'node-gyp/bin/node-gyp'

node.js - 如何使用node-fs从url将图像保存到本地

linux - 如何获取特定进程的 SMP 信息(在哪个核心上运行)

node.js - 如何让Winston每日文件轮换记录到相应级别的文件

javascript - ““Meteor - tsega/meteor-bootstrap3-datetimepicker 类型错误 : locale() locale it is not loaded from moment locales! “

c++ - 等待进程存在于 "native"C++ 中?

linux - 我如何附加到正在运行的进程,如 Linux 上的调试器?

image - 以流形式获取 ffmpeg png 输出(不是 png 文件)

c# - MemoryStream 不包含 GetBuffer() 的定义

iOS/swift : Set timeout for opening Streams