承诺解决子流 stdout 并拒绝子流 stderr
Promise resolving to child stream stdout and rejecting child stream stderr
我想构建一个使用 require('child_process').spawn
生成子进程的承诺。该进程将其输出流式传输到 stdout
并将其错误流式传输到 stderr
.
我希望承诺:
reject(child.stderr stream (or its data))
如果 child.stderr
发出任何数据。
resolve(child.stdout stream)
仅当未发出错误时。
我这样做是因为我想将承诺链接到:
- a
then
处理 child.stdout
流(将流上传到 S3 存储桶)。
- 一个
catch
可以处理 child.stderr 流,让我能够正确处理错误。
像这样结合承诺和处理流是否可行?
我正在考虑解决 stderr 但不确定如果有大量数据进入 stdout 而我处理速度不够快,那么 stdout 之间会发生什么。
在我看来,问题是在整个过程完成之前,您不知道自己是否曾在 stderr
上获得过数据,因为它可以随时将数据放在那里。
因此,您必须等待整个过程完成才能调用 resolve()
或 reject()
。而且,如果您随后希望将整个数据发送到其中任何一个,则必须缓冲它们。您可以在 stderr
上获得数据后立即调用 reject()
,但不能保证您拥有所有数据,因为它是一个流。
因此,如果您不想缓冲,最好让调用者直接查看流。
如果您可以缓冲数据,您可以像这样自己缓冲:
根据 node.js 文档中的 spawn 示例,您可以像这样向其添加承诺支持:
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)
});
我想构建一个使用 require('child_process').spawn
生成子进程的承诺。该进程将其输出流式传输到 stdout
并将其错误流式传输到 stderr
.
我希望承诺:
reject(child.stderr stream (or its data))
如果child.stderr
发出任何数据。resolve(child.stdout stream)
仅当未发出错误时。
我这样做是因为我想将承诺链接到:
- a
then
处理child.stdout
流(将流上传到 S3 存储桶)。 - 一个
catch
可以处理 child.stderr 流,让我能够正确处理错误。
像这样结合承诺和处理流是否可行? 我正在考虑解决 stderr 但不确定如果有大量数据进入 stdout 而我处理速度不够快,那么 stdout 之间会发生什么。
在我看来,问题是在整个过程完成之前,您不知道自己是否曾在 stderr
上获得过数据,因为它可以随时将数据放在那里。
因此,您必须等待整个过程完成才能调用 resolve()
或 reject()
。而且,如果您随后希望将整个数据发送到其中任何一个,则必须缓冲它们。您可以在 stderr
上获得数据后立即调用 reject()
,但不能保证您拥有所有数据,因为它是一个流。
因此,如果您不想缓冲,最好让调用者直接查看流。
如果您可以缓冲数据,您可以像这样自己缓冲:
根据 node.js 文档中的 spawn 示例,您可以像这样向其添加承诺支持:
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)
});