Node.js 'console.log асинхронный?

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

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

Ответ 1

Обновление: Начиная с Node 0.6 этот пост устарел, поскольку stdout теперь синхронно.

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

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

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 мы заканчиваем здесь, эта вещь наследуется от сокета. Таким образом, базовое значение Node состоит в том, чтобы вставлять данные в сокет, тогда терминал заботится обо всех остальных.

Пусть протестируйте его!

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 секунды, но Node требуется только 17 миллисекунд, чтобы вывести данные на терминал.

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

Значит да Node.js имеет значение для его неблокирующего promises.

Ответ 2

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

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

Ответ 3

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

(Ниже приведен пример командной строки, console.log async и console.error синхронизация)

На основе Node.js Doc

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

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

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

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

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