Update: Ab Knoten 0.6 ist dieser Beitrag veraltet, da stdout jetzt synchron ist .
Mal sehen, was console.log
eigentlich macht.
Zuallererst ist es Teil des Konsolenmoduls :
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Es werden also einfach einige Formatierungen und Schreibvorgänge durchgeführt process.stdout
, bisher nichts Asynchrones.
process.stdout
ist ein beim Start definierter Getter , der träge initialisiert wird. Ich habe einige Kommentare hinzugefügt, um die Dinge zu erklären:
.... 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;
});
Im Falle eines TTY und UNIX landen wir hier , dieses Ding erbt von Socket. Alles, was dieser Knoten grundsätzlich tut, ist, die Daten auf den Socket zu übertragen, und das Terminal kümmert sich um den Rest.
Lass es uns testen!
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);
Ergebnis
....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms
real 0m0.969s
user 0m0.068s
sys 0m0.012s
Das Terminal benötigt ungefähr 1 Sekunde, um den Socket-Inhalt auszudrucken, aber der Knoten benötigt nur 17 Millisekunden, um die Daten zum Terminal zu übertragen.
Gleiches gilt für den Stream-Fall, und auch der Dateifall wird asynchron behandelt .
Also ja, Node.js hält an seinen nicht blockierenden Versprechen fest.