Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.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
如何确保Node.js函数仅在流结束后运行?_Node.js_Callback_Stream - Fatal编程技术网

如何确保Node.js函数仅在流结束后运行?

如何确保Node.js函数仅在流结束后运行?,node.js,callback,stream,Node.js,Callback,Stream,通过尝试重新创建我曾经在C#中编写过的一些实用程序,我很快就了解了Node.js。我对我正在写的一个程序中发生的事情有点困惑。我想要这个程序做的是在文件系统上打开一个文件,gzip该文件,然后将gzip数据发送到另一台服务器。对于测试,我决定“将gzip数据保存到文件系统,然后将其读回以验证是否正确。” 因此,我希望我的程序能够做到: 创建输出文件 打印“创建的测试输出文件” 打印“尝试重新读取数据” 读取文件 将纯文本输出到控制台 结果是: 将创建输出文件 打印“正在尝试重新读取数据” 打印“

通过尝试重新创建我曾经在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()
      ,则输出文件为空。我猜这是因为它在写入之前关闭了流
    • 如果我调用
      gzipStream.end()
      ,我不会得到“Created test output file”消息,而是创建了一个
    编辑


    我想出了第二部分。在给定的代码中,在调用
    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
    。如果你能用一个例子把你的评论转换成一个答案,我很乐意接受。