Javascript 流在';数据';回拨是否已注册?
下面的示例使用Javascript 流在';数据';回拨是否已注册?,javascript,node.js,stream,Javascript,Node.js,Stream,下面的示例使用curl(假设它存在于系统中)下载由file\u url指定的文件 spawn()使用传递的参数返回调用curl的结果流curl.stdout.on将注册一个回调,该回调将被称为curl,将数据块流传输到我们的应用程序中,我们将将这些数据块写入文件,这是一个WriteStream var file = fs.createWriteStream(DOWNLOAD_DIR + file_name) var curl = spawn('curl', [file_url]) curl.s
curl
(假设它存在于系统中)下载由file\u url
指定的文件
spawn()
使用传递的参数返回调用curl
的结果流curl.stdout.on
将注册一个回调,该回调将被称为curl,将数据块流传输到我们的应用程序中,我们将将这些数据块写入文件,这是一个WriteStream
var file = fs.createWriteStream(DOWNLOAD_DIR + file_name)
var curl = spawn('curl', [file_url])
curl.stdout.on('data', function(data) {
file.write(data)
})
curl.stdout.on('end', function(data) {
file.end()
})
如果调用了spawn
,但在注册on(“数据”,[Function])
calback之前,curl
已经获取并返回一些数据,会发生什么情况
当我输入完这个问题后,我顿悟到内部流实现应该只是缓冲/收集所有这些数据块,如果注册了'data'
回调,则只发出'data'
事件
你能证实这一点和/或解释我错在哪里吗?简单的答案是Node.js是单线程的。来自curl进程的任何消息都将“排队”,一旦Javascript给它一个机会,就会被发出。因此,由于您在('data')…
回调上注册了,因此您没有给javascript发出任何数据的机会。如果您使用setTimeout
然后在('data')…
回调上设置,那么是的,您可能会丢失一些数据
测试蝙蝠
echo "Hello!"
无数据丢失:
var spawn = require('child_process').spawn;
var curl = spawn('test.bat');
console.log('before');
for (var i = 0; i < 2000000000; i++) {
//Waste some time
}
console.log('after');
curl.stdout.on('data', function (data) {
console.log('data: ' + data);
});
curl.stdout.on('end', function (data) {
console.log('end: ' + data);
});
setTimeout(function () { }, 10000); //Just to keep console open for 10 seconds
var spawn = require('child_process').spawn;
var curl = spawn('test.bat');
setTimeout(function () {
curl.stdout.on('data', function (data) {
console.log('data: ' + data);
});
curl.stdout.on('end', function (data) {
console.log('end: ' + data);
});
console.log('finished');
}, 10000);
哦,我明白了。这意味着我的见解不正确,但清楚地解释了为什么上面的代码段中没有数据丢失。如果我执行类似于setTimeout(cbThatRegistersOnData,0)
的操作,会发生什么情况?如果使用超时(0ms),则可能会丢失一些数据。进程需要时间启动(可能需要整整一秒钟)所以我怀疑你在使用0毫秒的超时时是否会丢失数据,但你正在运行一个竞争条件。仅仅因为你使用0毫秒的超时并不意味着你的代码的另一部分没有使用哑for循环(如上所述),它会等待一秒或更长时间,并导致你在数据发出后注册。谢谢你,有用的答案和示例。