Aktualizacja: Począwszy od Node 0.6 ten post jest przestarzały, ponieważ stdout jest teraz synchroniczny .
Zobaczmy, co console.log
tak naprawdę robi.
Przede wszystkim jest częścią modułu konsoli :
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Więc po prostu wykonuje pewne formatowanie i zapisuje process.stdout
, jak na razie nic asynchronicznego.
process.stdout
to getter zdefiniowany podczas uruchamiania, który jest inicjowany leniwie, dodałem kilka komentarzy, aby wyjaśnić:
.... code here...
process.__defineGetter__('stdout', function() {
if (stdout) return stdout;
if (binding.isatty(fd)) {
stdout = new tty.WriteStream(fd);
} else if (binding.isStdoutBlocking()) {
stdout = new fs.WriteStream(null, {fd: fd});
} else {
stdout = new net.Stream(fd);
stdout.readable = false;
}
return stdout;
});
W przypadku TTY i UNIXa kończymy tutaj , ta rzecz dziedziczy z gniazda. Więc wszystko, co w zasadzie robi ten węzeł, to wypychanie danych do gniazda, a następnie terminal zajmuje się resztą.
Przetestujmy to!
var data = '111111111111111111111111111111111111111111111111111';
for(var i = 0, l = 12; i < l; i++) {
data += data;
}
var start = Date.now();
console.log(data);
console.log('wrote %d bytes in %dms', data.length, Date.now() - start);
Wynik
....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms
real 0m0.969s
user 0m0.068s
sys 0m0.012s
Terminal potrzebuje około 1 sekundy na wydrukowanie zawartości gniazd, ale węzeł potrzebuje tylko 17 milisekund na przesłanie danych do terminala.
To samo dotyczy przypadku strumienia, a także przypadek pliku jest obsługiwany asynchronicznie .
Więc tak, Node.js spełnia swoje nieblokujące obietnice.
process.stdout.write()
gdziewrite()
jest z definicji asynchroniczne…console.warn () i console.error () są blokujące. Nie wracają, dopóki nie powiodą się podstawowe wywołania systemowe.
Tak, możliwe jest, że program zakończy działanie, zanim wszystko, co zostało zapisane na stdout, zostanie opróżnione. process.exit () natychmiast zakończy działanie node, nawet jeśli nadal istnieją zapisy w kolejce na standardowe wyjście. Aby uniknąć tego zachowania, należy użyć console.warn.
źródło
console.warn()
iconsole.error()
mają takie samo nieblokujące zachowanie jakconsole.log()
. Jest nawet pakiet do rozwiązania problemu w systemie Windows .Moje wnioski, po przeczytaniu dokumentów Node.js 10. * (załączone poniżej). polega na tym, że możesz użyć console.log do logowania, console.log jest synchroniczna i zaimplementowana na niskim poziomie c. Chociaż console.log jest synchroniczna, nie spowoduje problemów z wydajnością tylko wtedy, gdy nie rejestrujesz dużej ilości danych.
(Poniższy przykład wiersza poleceń demonstruje, console.log async i console.error to synchronizacja )
Na podstawie Node.js Doc's
$ node script.js 2> error.log | tee info.log
Mam nadzieję, że to pomoże
źródło
Console.log jest asynchroniczny w systemie Windows, podczas gdy jest synchroniczny w linux / mac. Aby uczynić console.log synchronicznym w systemie Windows, napisz tę linię na początku kodu, prawdopodobnie w pliku index.js. Każdy plik console.log po tej instrukcji będzie traktowany jako synchroniczny przez interpreter.
if (process.stdout._handle) process.stdout._handle.setBlocking(true);
źródło