Обновление: начиная с 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 мы попадаем сюда , эта вещь наследуется от сокета. Таким образом, все, что обычно делает этот узел, - это помещать данные в сокет, а все остальное выполняет терминал.
Давай проверим!
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 выполняет свои обещания о неблокировании.
process.stdout.write()
гдеwrite()
, по определению асинхронного ...console.warn () и console.error () блокируются. Они не возвращаются, пока базовые системные вызовы не завершатся успешно.
Да, программа может выйти до того, как все, что записано в stdout, будет сброшено. process.exit () немедленно завершит работу узла, даже если в stdout все еще есть записи в очереди. Вы должны использовать console.warn, чтобы избежать такого поведения.
источник
console.warn()
иconsole.error()
имеют такое же неблокирующее поведение, что иconsole.log()
. Есть даже пакет для решения проблемы в Windows .Мое заключение после прочтения документов Node.js 10. * (прилагается ниже). заключается в том, что вы можете использовать console.log для ведения журнала, console.log синхронна и реализована на низком уровне c. Хотя console.log является синхронным, он не вызовет проблем с производительностью, только если вы не регистрируете большой объем данных.
(Пример командной строки ниже демонстрирует, console.log async и console.error синхронизируются )
На основе Node.js Doc's
$ node script.js 2> error.log | tee info.log
Надеюсь, поможет
источник
Console.log асинхронен в Windows, тогда как в linux / mac он синхронен. Чтобы сделать console.log синхронным в Windows, напишите эту строку в начале вашего кода, вероятно, в файле index.js. Любой console.log после этого оператора будет рассматриваться интерпретатором как синхронный.
источник