如何确保Node.js函数仅在流结束后运行?
通过尝试重新创建我曾经在C#中编写过的一些实用程序,我很快就了解了Node.js。我对我正在写的一个程序中发生的事情有点困惑。我想要这个程序做的是在文件系统上打开一个文件,gzip该文件,然后将gzip数据发送到另一台服务器。对于测试,我决定“将gzip数据保存到文件系统,然后将其读回以验证是否正确。” 因此,我希望我的程序能够做到:如何确保Node.js函数仅在流结束后运行?,node.js,callback,stream,Node.js,Callback,Stream,通过尝试重新创建我曾经在C#中编写过的一些实用程序,我很快就了解了Node.js。我对我正在写的一个程序中发生的事情有点困惑。我想要这个程序做的是在文件系统上打开一个文件,gzip该文件,然后将gzip数据发送到另一台服务器。对于测试,我决定“将gzip数据保存到文件系统,然后将其读回以验证是否正确。” 因此,我希望我的程序能够做到: 创建输出文件 打印“创建的测试输出文件” 打印“尝试重新读取数据” 读取文件 将纯文本输出到控制台 结果是: 将创建输出文件 打印“正在尝试重新读取数据” 打印“
var inputFilePath=“data.xml”;
var fs=需要('fs');
var zlib=需要('zlib');
var inputStream=fs.createReadStream(inputFilePath)
.on('end',function(){
log(“创建的测试输出文件”);
});
var gzipStream=zlib.createGzip();
inputStream.pipe(gzipStream);
var outputFile=fs.createWriteStream('output.gzip');
管道(outputFile);
log('试图重新读取数据');
var testInput=fs.createReadStream('output.gzip');
var unzip=zlib.createGunzip();
testInput.pipe(解压).on('data',函数(块){
log(chunk.toString('utf8'));
});
我怀疑流媒体是异步发生的,这就是为什么我看到控制台输出的顺序与我预期的不同。如果这是真的,那就是一个问题,因为我需要在打开输出文件之前准备好它。我注意到writeable.end()
并认为这就是解决方案,但我不明白在不同的地方调用它时会发生什么:
- 如果在尝试读取文件之前调用
,则输出文件为空。我猜这是因为它在写入之前关闭了流outputFile.end()
- 如果我调用
,我不会得到“Created test output file”消息,而是创建了一个李>gzipStream.end()
我想出了第二部分。在给定的代码中,在调用
pipe()
之前,我应该从unzip
流中为data
事件设置处理程序。按照现在的代码设置方式,我正在设置处理管道返回的流上的事件,但从未从该流读取,因此从未调用我的处理程序。我偶然发现了这个解决方案。从概念上看,我想要一个订单的表达方式是:“当输入流中没有更多数据时,开始处理它生成的输出文件。”大大简化:
var inputFilePath = "data.xml";
var fs = require('fs');
var zlib = require('zlib');
function testOutput() {
console.log('Attempting to re-read the data.');
var testInput = fs.createReadStream('output.gzip');
var unzip = zlib.createGunzip();
unzip.on('data', function(chunk) {
console.log(chunk.toString('utf8'))
});
testInput.pipe(unzip);
};
// Load input file stream
var inputStream = fs.createReadStream(inputFilePath);
// Pipe the file stream into a gzip stream
var gzipStream = zlib.createGzip();
gzipStream.on('end', function() {
console.log("Created test output file.");
testOutput();
});
var outputFile = fs.createWriteStream('output.gzip');
inputStream.pipe(gzipStream).pipe(outputFile);
调用
pipe()
会清空inputStream
,然后调用testOutput()
的gzipStream
,这并不是nodejs的全部内容都是异步的吗?啊。让它工作的方法是从你的评论中得到启发的。诀窍是使需要输出文件的代码部分响应inputStream的end
。如果你能用一个例子把你的评论转换成一个答案,我很乐意接受。