Сохраняет ли write() (без обратного вызова) порядок в потоках записи node.js?

У меня есть программа 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), и я не уверен, что это может привести к нежелательному поведению (т. е. строки, написанные не в следующем порядке: строка1, строка2, строка3). Другими словами, я не знаю, следует ли использовать эту альтернативу (более сложный код и не уверен, что менее эффективен):

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

(или эквивалентная альтернатива с использованием серии async())

Эмпирически в моих тестах я всегда записывал файл в нужном порядке (я имею в виду первую строку 1, затем строку 2 и, наконец, строку 3). Тем не менее, я не знаю, произошло ли это случайно или вышеизложенное является правильным способом использования write().

Я понимаю, что запись в потоке, как правило, асинхронна (как и вся работа ввода-вывода), но мне интересно, сохраняют ли потоки в node.js внутренний буфер или аналогичный, который упорядочивает данные, поэтому каждый вызов write() не возвращается пока данные не будут помещены в этот буфер.

Приветствуются примеры использования write() в реальных программах. Спасибо!


person fgalan    schedule 16.04.2018    source источник


Ответы (1)


Сохраняет ли write() (без обратного вызова) порядок в потоках записи node.js?

Да, это так. Он сохраняет порядок ваших записей в этот конкретный поток. Все данные, которые вы записываете, проходят через потоковый буфер, который сериализует их.

но мне интересно, сохраняют ли потоки в node.js внутренний буфер или аналогичный, который упорядочивает данные, поэтому каждый вызов write() не возвращается до тех пор, пока данные не будут помещены в этот буфер.

Да, все данные проходят через потоковый буфер. Операция .write() не возвращает значение до тех пор, пока данные не будут успешно скопированы в буфер, если только не произойдет ошибка.

Обратите внимание, что если вы записываете какой-либо значительный объем данных, вам, возможно, придется обратить внимание на управление потоком (часто называемое противодавлением) в потоке. Он может создавать резервные копии и может сообщать вам, что вам нужно подождать, прежде чем писать больше, но он буферизует ваши записи в том порядке, в котором вы их отправляете.

Если операция .write() возвращает false, то поток сообщает вам, что вам нужно дождаться события drain, прежде чем писать дальше. Вы можете прочитать об этой проблеме в документации Node.js для .write() и в эта статья о противодавлении.

Ваш код также должен прослушивать событие error, чтобы обнаруживать любые ошибки при записи потока. Поскольку записи являются асинхронными, они могут произойти в более позднее время и не обязательно отражаются ни в возвращаемом значении из .write(), ни в параметре err обратного вызова .write(). Вы должны прослушивать событие error, чтобы убедиться, что вы видите ошибки в потоке.

person jfriend00    schedule 16.04.2018