Mise à jour: à partir de Node 0.6, ce post est obsolète, car stdout est désormais synchrone .
Eh bien, voyons ce que console.log
fait réellement.
Tout d'abord, il fait partie du module de console :
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Donc, il fait simplement du formatage et écrit process.stdout
, rien de asynchrone jusqu'à présent.
process.stdout
est un getter défini au démarrage qui est initialisé paresseusement, j'ai ajouté quelques commentaires pour expliquer les choses:
.... 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;
});
Dans le cas d'un TTY et UNIX, nous nous retrouvons ici , cette chose hérite de socket. Donc, tout ce que fait ce nœud est essentiellement de pousser les données sur la socket, puis le terminal s'occupe du reste.
Testons-le!
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);
Résultat
....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms
real 0m0.969s
user 0m0.068s
sys 0m0.012s
Le terminal a besoin d'environ 1 seconde pour imprimer le contenu des sockets, mais le nœud n'a besoin que de 17 millisecondes pour pousser les données vers le terminal.
Il en va de même pour le cas de flux, et le cas de fichier est également traité de manière asynchrone .
Alors oui, Node.js tient ses promesses non bloquantes.