Atualização: a partir do Node 0.6, este post está obsoleto, já que stdout é síncrono agora.
Bem, vamos ver o que console.log
realmente faz.
Em primeiro lugar, faz parte do módulo do console :
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Portanto, ele simplesmente formata e grava process.stdout
, nada de forma assíncrona até agora.
process.stdout
é um getter definido na inicialização que é inicializado lentamente, adicionei alguns comentários para explicar as coisas:
.... 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;
});
No caso de um TTY e UNIX a gente acaba aqui , essa coisa herda do socket. Portanto, tudo o que o nó faz basicamente é enviar os dados para o soquete, e o terminal cuida do resto.
Vamos testar!
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
O terminal precisa de cerca de 1 segundo para imprimir o conteúdo dos sockets, mas o nó só precisa de 17 milissegundos para enviar os dados para o terminal.
O mesmo vale para o caso de fluxo e também o caso de arquivo é tratado de forma assíncrona .
Então, sim, o Node.js se mantém fiel às suas promessas de não bloqueio.
process.stdout.write()
ondewrite()
está, por definição, assíncrono ...console.warn () e console.error () estão bloqueando. Eles não retornam até que as chamadas de sistema subjacentes sejam bem-sucedidas.
Sim, é possível que um programa saia antes que tudo escrito em stdout seja liberado. process.exit () encerrará o nó imediatamente, mesmo se ainda houver gravações enfileiradas no stdout. Você deve usar console.warn para evitar esse comportamento.
fonte
console.warn()
econsole.error()
têm o mesmo comportamento sem bloqueio deconsole.log()
. Existe até um pacote para resolver o problema no Windows .Minha conclusão, depois de ler Node.js 10. * docs (anexo abaixo). é que você pode usar console.log para registro, console.log é síncrono e implementado em baixo nível c. Embora o console.log seja sincronizado, ele não causará problemas de desempenho apenas se você não registrar uma grande quantidade de dados.
(O exemplo de linha de comando abaixo demonstra, console.log async e console.error é sync )
Baseado em Node.js Doc's
$ node script.js 2> error.log | tee info.log
Espero que ajude
fonte
Console.log é assíncrono no Windows enquanto é síncrono no linux / mac. Para tornar o console.log síncrono no Windows, escreva esta linha no início do seu código, provavelmente no arquivo index.js. Qualquer console.log após esta instrução será considerado síncrono pelo interpretador.
fonte