2011-02-26 18 views
75

¿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.es node.js 'console.log asincrónico?

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

Respuesta

89

Actualización: A partir de Nodo 0,6 este post es obsoleta, ya que la salida estándar es sincrónica ahora.

Bien, veamos qué hace realmente console.log.

En primer lugar es parte de la console module:

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

Por lo tanto, simplemente hace algún formato y escribe en process.stdout, nada asíncrono hasta ahora.

process.stdout es un captador defined on startup que se inicializa con pereza, he añadido algunos comentarios para explicar 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 caso de un TTY y UNIX terminamos here, esta cosa hereda de zócalo. Entonces, todo lo que el nodo básicamente hace es enviar los datos al socket, luego el terminal se ocupa del resto.

¡Pruébelo!

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 tomas de corriente, pero nodo sólo tiene 17 milisegundos para empujar los datos a la terminal.

Lo mismo ocurre con la caja de flujo, y también el caso de archivo se maneja asynchronous.

So Node.js se mantiene fiel a sus promesas de no bloqueo.

+2

Actualización: la salida estándar en Node.js es ahora sincrónica: http://groups.google.com/group/nodejs/browse_thread/thread/8c85c2dae1a1f585 – dhruvbird

+1

creo que esto es obsoleto en la actualidad: https://github.com/nodejs/node/issues/3524#issuecomment-151097761 – tforgione

+0

@ IvoWetzel Voy a tener que rechazar esto ahora, ya que es obsoleto. –

23

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 programa salga antes de que todo lo escrito en stdout se haya 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.

+1

Esto no es cierto para el Nodo 0.10.25 en Windows. 'console.warn()' y 'console.error()' tienen el mismo comportamiento no bloqueante de 'console.log()'. Incluso hay un [paquete para resolver el problema en Windows] (https://www.npmjs.org/package/exit). –

9

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 consola.error es sincronización)

Basado en Node.js Doc's

Las funciones de la consola son sincrónicas cuando el destino es un terminal o un archivo (para evitar la pérdida de mensajes en caso de salida prematura) y asíncrona cuando se trata de una tubería (para evitar el bloqueo por largos períodos de tiempo).

Es decir, en el ejemplo siguiente, la salida estándar es no bloqueante, mientras stderr está bloqueando:

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

En el uso diario, el bloqueo/no-bloqueo dicotomía no es algo que debería preocuparse a menos que ingrese grandes cantidades de datos.

creo que sirve