【问题标题】:callback to handle completion of pipe回调处理管道完成
【发布时间】:2012-07-11 23:15:55
【问题描述】:

我正在使用以下 node.js 代码从某个 url 下载文档并将其保存在磁盘中。 我想知道何时下载文档。我没有看到任何带有管道的回调。或者,是否有任何可以在下载完成时捕获的“结束”事件?

request(some_url_doc).pipe(fs.createWriteStream('xyz.doc'));

【问题讨论】:

    标签: node.js


    【解决方案1】:

    流是EventEmitters,因此您可以收听某些事件。正如你所说,有一个finish 请求事件(以前是end)。

     var stream = request(...).pipe(...);
     stream.on('finish', function () { ... });
    

    有关哪些活动可用的更多信息,您可以查看stream documentation page

    【讨论】:

    • var r = request(...).on("end",function(){/* CALLBACK */}).pipe(...);
    • 对我来说,事件“关闭”而不是“结束”有效r.on('close'), function () {...})
    • “结束”事件现在是“完成”管道事件:nodejs.org/api/stream.html#stream_event_finish
    • 'end' 事件仍然存在并用于可读流。可写流使用“完成”。这是因为 Transform 流是两者的混合,需要区分事件。
    • 这个线程很好地总结了如何使用节点流。
    【解决方案2】:

    基于nodejs文档,http://nodejs.org/api/stream.html#stream_event_finish, 它应该处理 writableStream 的 finish 事件。

    var writable = getWriteable();
    var readable = getReadable();
    readable.pipe(writable);
    writable.on('finish', function(){ ... });
    

    【讨论】:

    • 接受的答案不适用于节点 v0.12.7,但您的解决方案可以。
    【解决方案3】:

    代码 sn-p 用于通过 http(s) 从 Web 将内容传输到文件系统。正如@starbeamrainbowlabs 注意到事件finish 所做的工作

    var tmpFile = "/tmp/somefilename.doc";
    
    var ws = fs.createWriteStream(tmpFile);
    ws.on('finish', function() {
      // pipe done here, do something with file
    });
    
    var client = url.slice(0, 5) === 'https' ? https : http;
    client.get(url, function(response) {
      return response.pipe(ws);
    });
    

    【讨论】:

    • “完成”对我有用,而“结束”则不行。谢谢!
    • 在一种特殊情况下,finish 似乎在所有预期字节到达之前触发
    【解决方案4】:

    这是一个处理请求中的错误并在文件写入后调用回调的解决方案:

    request(opts)
        .on('error', function(err){ return callback(err)})
        .pipe(fs.createWriteStream(filename))
        .on('finish', function (err) {
            return callback(err);
        });
    

    【讨论】:

      【解决方案5】:

      我发现了一个与此上下文有关的问题的稍微不同的解决方案。值得分享的想法。

      大部分示例从文件创建readStreams。但在我的情况下,readStream 必须从来自消息池的JSON 字符串创建。

      var jsonStream = through2.obj(function(chunk, encoding, callback) {
                          this.push(JSON.stringify(chunk, null, 4) + '\n');
                          callback();
                      });
      // message.value --> value/text to write in write.txt 
      jsonStream.write(JSON.parse(message.value));
      var writeStream = sftp.createWriteStream("/path/to/write/write.txt");
      
      //"close" event didn't work for me!
      writeStream.on( 'close', function () {
          console.log( "- done!" );
          sftp.end();
          }
      );
      
      //"finish" event didn't work for me either!
      writeStream.on( 'close', function () {
          console.log( "- done!"
              sftp.end();
              }
      );
      
      // finally this worked for me!
      jsonStream.on('data', function(data) {
          var toString = Object.prototype.toString.call(data);
          console.log('type of data:', toString);
          console.log( "- file transferred" );
      });
      
      jsonStream.pipe( writeStream );
      

      【讨论】:

      • 你有两个“关闭”处理程序而不是监听“完成”,也许这就是原因。 “完成”事件对我有用。
      猜你喜欢
      • 2015-11-16
      • 2020-12-30
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多