Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 流在';数据';回拨是否已注册?_Javascript_Node.js_Stream - Fatal编程技术网

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循环(如上所述),它会等待一秒或更长时间,并导致你在数据发出后注册。谢谢你,有用的答案和示例。