承诺解决子stream标准输出和拒绝子stream标准错误

我想build立一个使用require('child_process').spawn产生subprocess的承诺。 这个过程把它的输出输出到stdout ,把它的错误输出到stdout stderr

我希望承诺:

  • 如果child.stderr发出任何数据,则reject(child.stderr stream (or its data))
  • resolve(child.stdout stream)只有当没有错误发射。

我这样做是因为我想把承诺链接到:

  • then处理child.stdoutstream(将stream上传到S3存储桶)。
  • 一个可以处理child.stderrstream的catch ,允许我正确处理错误。

把这样的承诺和stream程结合起来是否可行? 我正在考虑在stderr上工作,但是不知道如何在stdout之间发生什么,如果有大量的数据进入它,我不处理它的速度不够快。

正如我所看到的那样,问题在于,在整个过程完成之前,您不知道是否获得了stderr数据,因为它可以随时将数据存储在那里。

因此,在调用resolve()reject()之前,必须等待整个过程完成。 而且,如果您希望将全部数据发送到其中一个,则必须缓冲这些数据。 您可以在获得stderr数据后立即调用reject() ,但不能保证所有数据都是因为它是stream。

所以,如果你不想缓冲,最好让调用者直接看到stream。

如果你可以缓冲数据,你可以像这样缓冲它:

基于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) });