【问题标题】:Does write() (without callback) preserve order in node.js write streams?write()(没有回调)是否保留 node.js 写入流中的顺序?
【发布时间】:2018-09-26 16:10:44
【问题描述】:

我有一个 node.js 程序,我在其中使用流将信息写入 SFTP 服务器。像这样的东西(简化版):

var conn = new SSHClient();
process.nextTick(function (){      
   conn.on('ready', function () {
      conn.sftp(function (error, sftp) {
         var writeStream = sftp.createWriteStream(filename);
         ...
         writeStream.write(line1);
         writeStream.write(line2);
         writeStream.write(line3);
         ...
      });
    }).connect(...);
});

请注意,我没有使用(可选)回调参数(在write() API specification 中描述),我不确定这是否会导致不良行为(即未按以下顺序写入的行:line1、line2、line3 )。换句话说,我不知道是否应该使用这种替代方案(更复杂的代码并且不确定效率是否更低):

writeStream.write(line1, ..., function() {
   writeStream.write(line2, ..., function() {
      writeStream.write(line3);
   });
});

(或使用 async series() 的等效替代方案)

根据经验,在我的测试中,我总是以所需的顺序写入文件(我的意思是,首先是第 1 行,然后是第 2 行,最后是第 3 行)。但是,我现在不知道这是偶然发生的,还是上面是使用 write() 的正确方法。

我知道在流中写入通常是异步的(所有 I/O 工作都应该如此),但我想知道 node.js 中的流是否保留了内部缓冲区或类似的东西来保持数据有序,所以每个 write() 调用都不会'在数据被放入这个缓冲区之前不返回。

非常欢迎在实际程序中使用 write() 的示例。谢谢!

【问题讨论】:

    标签: node.js node-streams


    【解决方案1】:

    write()(没有回调)是否保留 node.js 写入流中的顺序?

    是的。它保留了您对该特定流的写入顺序。您正在写入的所有数据都经过序列化它的流缓冲区。

    但我想知道 node.js 中的流是否保留了一个内部缓冲区或类似的保持数据有序的缓冲区,因此每个 write() 调用在数据放入此缓冲区之前不会返回。

    是的,所有数据都通过流缓冲区。除非发生错误,否则.write() 操作在数据成功复制到缓冲区之前不会返回。

    请注意,如果您要写入大量数据,您可能需要注意流上的流量控制(通常称为背压)。它可以备份,并且可能会告诉您在写入更多内容之前需要等待,但它会按照您发送它们的顺序缓冲您的写入。

    如果.write() 操作返回false,则流告诉您需要等待drain 事件,然后再写入。您可以在node.js docs for .write()this article about backpressure 中阅读有关此问题的信息。

    您的代码还需要侦听error 事件以检测写入流时的任何错误。因为写入是异步的,所以它们可能会在稍后发生,并且不一定反映在来自.write() 的返回值或err 参数到.write() 回调中。您必须监听 error 事件以确保您在流中看到错误。

    【讨论】:

      猜你喜欢
      • 2011-12-26
      • 2012-06-29
      • 2010-10-14
      • 1970-01-01
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2021-03-25
      相关资源
      最近更新 更多