es node.js ‘console.log asincrónico?

¿Están console.log/debug/warn/error en node.js asynchrounous? Quiero decir que la ejecución del código JavaScript se detendrá hasta que se imprima en la pantalla o se imprimirá en una etapa posterior.

Además, estoy interesado en saber si es posible que un console.log NO muestre nada si la instrucción inmediatamente después de bloquear el nodo.

Actualización: comenzando con el nodo 0.6, esta publicación está obsoleta, ya que stdout ahora es síncrona .

Bien, veamos qué hace console.log realidad.

En primer lugar, es parte del módulo de la consola :

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

Por lo tanto, simplemente formatea y escribe para process.stdout . Sin embargo, nada asíncrono hasta el momento.

process.stdout es un getter definido en el inicio que se inicializa de forma perezosa, he agregado algunos comentarios para explicar las cosas:

 .... 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; }); 

En el caso de un TTY y UNIX que terminamos aquí , esto hereda del socket. Entonces, todo lo que el nodo básicamente hace es enviar los datos al socket, luego el terminal se ocupa del rest.

¡Probémoslo!

 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); 

Resultado

 ....a lot of ones....1111111111111111 wrote 208896 bytes in 17ms real 0m0.969s user 0m0.068s sys 0m0.012s 

El terminal necesita alrededor de 1 segundo para imprimir el contenido de los sockets, pero el nodo solo necesita 17 milisegundos para enviar los datos al terminal.

Lo mismo ocurre con el caso de transmisión, y también el caso de archivo obtiene asincrónico .

Entonces, sí, Node.js se mantiene fiel a sus promesas de no locking.

console.warn () y console.error () están bloqueando. No vuelven hasta que las llamadas al sistema subyacentes hayan tenido éxito.

Sí, es posible que un progtwig salga antes de que todo lo escrito en stdout haya sido eliminado. process.exit () terminará el nodo inmediatamente, incluso si aún hay escrituras en cola para stdout. Debería usar console.warn para evitar este comportamiento.

Mi conclusión, después de leer Node.js 10. * documentos (Adjunto a continuación). es que puede usar console.log para el registro, console.log es sincrónico e implementado en bajo nivel c. Aunque console.log es sincrónico, no causará un problema de rendimiento solo si no está registrando una gran cantidad de datos.

(El siguiente ejemplo de línea de comandos demuestra, console.log async y console.error es sincronización )

Basado en el documento de Node.js

Las funciones de la consola son síncronas cuando el destino es un terminal o un archivo (para evitar mensajes perdidos en caso de salida prematura) y asíncrono cuando es un conducto (para evitar el locking durante largos períodos de tiempo).

Es decir, en el siguiente ejemplo, stdout no bloquea mientras stderr está bloqueando:

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

En el uso diario, la dicotomía locking / no locking no es algo de lo que deba preocuparse a menos que> registre grandes cantidades de datos.

Espero eso ayude

Console.log es asíncrono en Windows mientras es sincrónico en ubuntu / mac. Para hacer que console.log sea sincrónico en Windows, escriba esta línea al comienzo de su código probablemente en el archivo index.js. Cualquier consola.log después de esta statement se considerará sincrónica por el intérprete.

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