【发布时间】:2016-04-30 12:34:09
【问题描述】:
我正在生成一个产生大量数据的孩子(我在这里使用“ls -lR /”作为示例)。我想一次异步读取孩子的标准输出 100 个字节。
所以我想做:get100().then(process100).then(get100).then(process100).then(...
由于某种原因,这段代码只循环了 3 次,并且我停止接收 Readable 事件。我想不通为什么?
var Promise = require('bluebird');
var spawn = require("child_process").spawn;
var exec = spawn( "ls", [ "-lR", "/"] );
var get100 = function () {
return new Promise(function(resolve, reject) {
var tryTransfer = function() {
var block = exec.stdout.read(100);
if (block) {
console.log("Got 100 Bytes");
exec.stdout.removeAllListeners('readable');
resolve();
} else console.log("Read Failed - not enough bytes?");
};
exec.stdout.on('readable', tryTransfer);
});
};
var forEver = Promise.method(function(action) {
return action().then(forEver.bind(null, action));
});
forEver(
function() { return get100(); }
)
【问题讨论】:
-
这似乎是一种非常复杂的方式来做一个简单的
ls。想做什么?读取的 100 个字节如何处理? -
我并没有真正运行 ls。我正在运行一些生成大量数据的专有 .exe。我有一份消费者名单。我需要获取前 100 个字节,添加一个标头,然后将其发送给第一个消费者,接下来的 100 + 标头发送给第二个消费者,等等。我正在尝试异步执行此操作。
-
我明白了,因为 exec.stdout 是一个流,你可以坚持使用流。我正在写一个anwser。
-
我想我至少找到了部分问题。我认为“可读”事件是针对已到达缓冲区的一些字节发送的。在我们读取此字节数之前,即使有更多字节到达,我们也不会收到另一个事件。
-
根据文档,
readable在数据块可用时触发,无论其大小如何。我认为问题可能是输入流的读取速度太快,并且有时 100 个字节不可用,因此您的处理就停止了。 .exe 的输出有多大/巨大?将其存储在文件中并处理该文件可能是一种解决方案,您将拥有更多控制权。就像我在下面所说的那样,流式传输/处理一个巨大的 2GB csv 文件对于 nodejs 来说是没有问题的。
标签: node.js stream child-process