Bagaimana NodeJS bisa “non-blocking”?

14

Saya sedang belajar NodeJS dan hanya ingin mengklarifikasi sesuatu. Dalam beberapa tutorial pengantar dan buku sejauh ini, sangat awal mereka telah menggambarkan arsitektur "non-blocking" Node - atau lebih tepatnya bahwa mungkin (dan direkomendasikan, seluruh poin) untuk kode dalam cara yang tidak menghalangi.

Jadi misalnya, contoh ini diberikan dalam buku yang saya baca tentang cara asinkron untuk mendapatkan data dari database.

http.createServer(function (req, res) {
  database.getInformation(function (data) {
      res.writeHead(200);
      res.end(data);
  });
});

Apa yang terjadi (seperti yang saya pahami) adalah Node membuat panggilan ke database, kemudian melanjutkan pemrosesan apa pun yang mungkin berikutnya pada tumpukan panggilan. Ketika permintaan database selesai, variabel data dalam fungsi panggilan balik anonim akan diisi dan fungsi itu ditambahkan ke tumpukan panggilan (dan kemudian dieksekusi ketika Node sampai ke sana).

Pertanyaan saya adalah, apa sebenarnya yang memproses permintaan basis data? Tentunya Node harus memblokir sementara itu melakukan itu? Apa yang menangani permintaan basis data? Atau jika Node sedang menunggu permintaan GET HTTP asinkron ke sumber daya eksternal, apa yang menangani permintaan itu yang memungkinkan Node untuk terus memproses tumpukan panggilan dan menjadi "non-pemblokiran"?

Anonim
sumber

Jawaban:

17

Ketika Node.js dideskripsikan sebagai "non-blocking", itu secara spesifik berarti bahwa IO-nya adalah non-blocking. Node menggunakan libuv untuk menangani IO-nya dengan cara platform-agnostik. Pada Windows, ia menggunakan port penyelesaian IO, pada Unix, ia menggunakan epoll / kqueue / select / etc. Jadi, itu membuat permintaan IO non-pemblokiran (yang mungkin memiliki pemantauan utas latar belakang, tetapi ini tidak pernah terkena JavaScript) dan akibatnya, itu mengantri dalam loop acara yang memanggil panggilan balik JavaScript pada main (baca: hanya) utas JavaScript.

Untuk database, itu tergantung pada bagaimana perpustakaan ditulis. Jika menggunakan HTTP untuk berkomunikasi (seperti beberapa database NoSQL lakukan), maka itu dapat dengan mudah ditulis dalam JavaScript murni menggunakan httppustaka simpul standar . Jika itu dilakukan dengan cara lain, itu terserah perpustakaan. Itu bisa ditulis dalam C / C ++ dan menggunakan utas latar belakang asalkan abstraksi itu tidak pernah terkena JavaScript.

Adapun pertanyaan Anda tentang apa yang "memproses" permintaan basis data, idealnya semua yang harus dilakukan adalah mengirim pesan sederhana ke perpustakaan (mis. Pernyataan SQL atau permintaan lain atau permintaan untuk terhubung), dan pada saat itu JavaScript Anda terus berdengung. Ketika perpustakaan siap untuk mengirim pesan kembali, itu mengirim pesan kembali ke antrian acara node yang menjalankan panggilan balik, yang memungkinkan potongan kode untuk berjalan.

ckknight
sumber
Ada netpaket ketika http tidak tersedia.
Florian Margaine
Detail yang mungkin membantu. Node memanfaatkan mesin V8 JS. Salah satu fitur terbaik V8 adalah kemudahan mengikat proses C / C ++ ke panggilan JS. Fungsi JavaScript memblokir tetapi semua fungsi tidak memanggil sesuatu di bawah kap yang tidak memblokir. Kemudian fungsi JS lain merespons ketika proses itu dilakukan. Fungsi JS memblokir satu sama lain berarti Anda tidak akan pernah memiliki dua hal yang mencoba melakukan sesuatu seperti menjadwalkan penulisan ke lokasi file yang sama pada saat yang sama di mana saya menganggap kebutuhan multi-threaded harus dikelola. Selalu jelas permintaan mana yang didahulukan untuk tujuan antrian.
Erik Reppen