Pembaruan: Dimulai dengan Node 0.6, posting ini sudah usang, karena stdout sudah sinkron sekarang.
Baiklah, mari kita lihat apa yang console.logsebenarnya dilakukannya.
Pertama-tama itu adalah bagian dari modul konsol :
exports.log = function() {
process.stdout.write(format.apply(this, arguments) + '\n');
};
Jadi itu hanya melakukan beberapa pemformatan dan penulisan ke process.stdout, sejauh ini tidak ada yang asinkron.
process.stdoutadalah pengambil yang didefinisikan pada startup yang diinisialisasi dengan malas, saya telah menambahkan beberapa komentar untuk menjelaskan hal-hal:
.... 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;
});
Dalam kasus TTY dan UNIX kami berakhir di sini , hal ini mewarisi dari soket. Jadi semua yang dilakukan node itu pada dasarnya adalah mendorong data ke soket, lalu terminal akan mengurus sisanya.
Mari kita uji!
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);
Hasil
....a lot of ones....1111111111111111
wrote 208896 bytes in 17ms
real 0m0.969s
user 0m0.068s
sys 0m0.012s
Terminal membutuhkan sekitar 1 detik untuk mencetak konten soket, tetapi node hanya membutuhkan 17 milidetik untuk mendorong data ke terminal.
Hal yang sama berlaku untuk kasus aliran, dan juga kasus file ditangani secara asinkron .
Jadi ya, Node.js memegang teguh janji non-pemblokirannya.