консольный журнал node.js является асинхронным? - PullRequest
88 голосов
/ 26 февраля 2011

Являются ли console.log/debug/warn/error в node.js асинхронными?Я имею в виду, остановится ли выполнение кода javascript, пока материал не будет напечатан на экране, или он будет напечатан на более позднем этапе?

Кроме того, мне интересно знать, возможно ли для console.log НЕ отображать что-либо, еслиоператор сразу после сбоя узла.

Ответы [ 4 ]

97 голосов
/ 26 февраля 2011

Обновление: Начиная с узла 0.6, этот пост устарел, так как стандартный вывод синхронен сейчас.

Хорошо, давайте посмотрим, что на самом деле делает console.log. 1008 *

Прежде всего, это часть консольного модуля :

exports.log = function() {
  process.stdout.write(format.apply(this, arguments) + '\n');
};

Так что он просто выполняет некоторое форматирование и записывает в process.stdout, пока ничего асинхронного.

process.stdout - это метод получения , определенный при запуске , который лениво инициализируется, я добавил несколько комментариев для объяснения вещей:

.... code here...
process.__defineGetter__('stdout', function() {
  if (stdout) return stdout;                            // only initialize it once 

  /// many requires here ...

  if (binding.isatty(fd)) {                             // a terminal? great!
    stdout = new tty.WriteStream(fd);
  } else if (binding.isStdoutBlocking()) {              // a file?
    stdout = new fs.WriteStream(null, {fd: fd});
  } else {
    stdout = new net.Stream(fd);                        // a stream? 
                                                        // For example: node foo.js > out.txt
    stdout.readable = false;
  }

  return stdout;
});

В случае TTY и UNIX мы получаем здесь , эта вещь наследуется от сокета. Таким образом, все, что делает этот узел, в основном, это передает данные в сокет, а затем терминал позаботится обо всем остальном.

Давайте проверим это!

var data = '111111111111111111111111111111111111111111111111111';
for(var i = 0, l = 12; i < l; i++) {
    data += data; // warning! gets very large, very quick
}

var start = Date.now();
console.log(data);
console.log('wrote %d bytes in %dms', data.length, Date.now() - start);

Результат

....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms

real    0m0.969s
user    0m0.068s
sys  0m0.012s

Терминалу требуется около 1 секунды для распечатки содержимого сокетов, но узлу требуется всего 17 миллисекунд для передачи данных на терминал.

То же самое относится и к регистру потока, а также регистр файла получает дескриптор асинхронный .

Так что да Node.js остается верным своим неблокирующим обещаниям.

26 голосов
/ 01 марта 2011

console.warn () и console.error () блокируются.Они не возвращаются до тех пор, пока базовые системные вызовы не будут выполнены успешно.

Да, программа может завершиться до того, как все данные, записанные в stdout, будут сброшены.process.exit () немедленно завершит работу узла, даже если записи в очередь все еще находятся в очереди.Вы должны использовать console.warn, чтобы избежать этого поведения.

11 голосов
/ 12 января 2015

Мой вывод, после прочтения Node.js 10. * docs (прилагается ниже). является то, что вы можете использовать console.log для ведения журнала, console.log является синхронным и реализован на низком уровне c. Хотя console.log является синхронным, он не вызовет проблем с производительностью, только если вы не регистрируете огромное количество данных.

(Пример командной строки ниже демонстрирует: console.log async и console.error: sync )

На основе Node.js Док.

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

То есть в следующем примере stdout неблокирует, а stderr блокирует:

$ node script.js 2> error.log | tee info.log

При ежедневном использовании блокирующая / неблокирующая дихотомия - это не то, о чем вам следует беспокоиться, если вы не> регистрируете огромные объемы данных.

Надеюсь, это поможет

3 голосов
/ 27 марта 2018

Console.log асинхронен в Windows, в то время как синхронно в Linux / Mac.Чтобы сделать console.log синхронным в Windows, напишите эту строку в начале кода, вероятно, в файле index.js.Любой console.log после этого оператора будет рассматриваться интерпретатором как синхронный.

if (process.stdout._handle) process.stdout._handle.setBlocking(true);
...