Rumah > Artikel > hujung hadapan web > Mari kita bincangkan tentang gelung acara dalam Node
Gelung peristiwa ialah bahagian asas Node.js Ia mendayakan pengaturcaraan tak segerak dengan memastikan bahawa utas utama tidak disekat Memahami gelung peristiwa adalah penting untuk membina aplikasi yang cekap. Artikel berikut akan memberi anda pemahaman yang mendalam tentang gelung acara dalam Node.
Anda telah lama menggunakan Node.js, membina beberapa apl, mencuba modul yang berbeza, malah berasa selesa dengan pengaturcaraan tak segerak. Tetapi sesuatu terus mengganggu anda - gelung acara.
Jika anda seperti saya, anda telah menghabiskan berjam-jam membaca dokumentasi dan menonton video cuba memahami gelung acara. Tetapi walaupun sebagai pembangun yang berpengalaman, anda mungkin menghadapi masalah memahami sepenuhnya cara ia berfungsi. Itulah sebabnya saya telah menyediakan panduan visual ini untuk membantu anda memahami sepenuhnya gelung acara Node.js. Jadi, duduklah, ambil secawan kopi dan mari selami dunia gelung acara Node.js. [Cadangan tutorial berkaitan: tutorial video nodejs, Pengajaran pengaturcaraan]
Kami akan bermula dari Kajian semula pengaturcaraan tak segerak dalam JavaScript bermula. Walaupun JavaScript digunakan dalam aplikasi web, mudah alih dan desktop, adalah penting untuk diingat bahawa, pada terasnya, JavaScript ialah bahasa berutas tunggal yang segerak, menyekat. Marilah kita memahami ayat ini melalui coretan kod pendek.
// index.js function A() { console.log("A"); } function B() { console.log("B"); } A() B() // Logs A and then BJavaScript adalah segerak
Anda mungkin pernah mengalami perkara ini dalam penyemak imbas anda. Apabila aplikasi web berjalan dalam penyemak imbas dan melaksanakan beberapa blok kod intensif tanpa mengembalikan kawalan kepada penyemak imbas, penyemak imbas mungkin membeku, yang dipanggil menyekat. Penyemak imbas disekat daripada terus memproses input pengguna dan melaksanakan tugas lain sehingga aplikasi web mengembalikan kawalan pemproses kepada penyemak imbas.
JavaScript adalah satu-benangNode.js Runtime ialah persekitaran yang anda boleh gunakan tanpa menggunakan penyemak imbas Gunakan dan jalankan program JavaScript. Teras - masa jalan Node, terdiri daripada tiga komponen utama.
Kebergantungan luaran — seperti V8, libuv, crypto, dll. — adalah ciri yang diperlukan Node.jsialah perpustakaan sumber terbuka merentas platform yang ditulis dalam bahasa C. Dalam masa jalan Node.js, peranannya adalah untuk menyediakan sokongan untuk mengendalikan operasi tak segerak. Mari kita lihat bagaimana ia berfungsi.
Pelaksanaan kod dalam masa jalan Node.js让我们来概括一下代码在 Node 运行时中的执行方式。在执行代码时,位于图片左侧的 V8 引擎负责 JavaScript 代码的执行。该引擎包含一个内存堆(Memory heap)和一个调用栈(Call stack)。
每当声明变量或函数时,都会在堆上分配内存。执行代码时,函数就会被推入调用栈中。当函数返回时,它就从调用栈中弹出了。这是对栈数据结构的简单实现,最后添加的项是第一个被移除。在图片右侧,是负责处理异步方法的 libuv。
每当我们执行异步方法时,libuv 接管任务的执行。然后使用操作系统本地异步机制运行任务。如果本地机制不可用或不足,则利用其线程池来运行任务,并确保主线程不被阻塞。
首先,让我们来看一下同步代码执行。以下代码由三个控制台日志语句组成,依次记录“First”,“Second”和“Third”。我们按照运行时执行顺序来查看代码。
// index.js console.log("First"); console.log("Second"); console.log("Third");
以下是 Node 运行时执行同步代码的可视化展示。
执行的主线程始终从全局作用域开始。全局函数(如果我们可以这样称呼它)被推入堆栈中。然后,在第 1 行,我们有一个控制台日志语句。这个函数被推入堆栈中。假设这个发生在 1 毫秒时,“First” 被记录在控制台上。然后,这个函数从堆栈中弹出。
执行到第 2 行时。假设到第 2 毫秒了,log 函数再次被推入堆栈中。“Second”被记录在控制台上,并弹出该函数。
最后,执行到第 3 行了。第 3 毫秒时,log 函数被推入堆栈,“Third”将记录在控制台上,并弹出该函数。此时已经没有代码要执行,全局也被弹出。
接下来,让我们看一下异步代码执行。有以下代码片段:包含三个日志语句,但这次第二个日志语句传递给了fs.readFile()
作为回调函数。
执行的主线程始终从全局作用域开始。全局函数被推入堆栈。然后执行到第 1 行,在第 1 毫秒时,“First”被记录在控制台中,并弹出该函数。然后执行移动到第 2 行,在第 2毫秒时,readFile
方法被推入堆栈。由于 readFile
是异步操作,因此它会转移(off-loaded)到 libuv。
JavaScript 从调用堆栈中弹出了 readFile
方法,因为就第 2 行的执行而言,它的工作已经完成了。在后台,libuv 开始在单独的线程上读取文件内容。在第 3 毫秒时,JavaScript 继续进行到第 5 行,将 log 函数推入堆栈,“Third”被记录到控制台中,并将该函数弹出堆栈。
大约在第 4 毫秒左右,假设文件读取任务已经完成,则相关回调函数现在会在调用栈上执行, 在回调函数内部遇到 log 函数。
log 函数推入到到调用栈,“Second”被记录到控制台并弹出 log 函数 。由于回调函数中没有更多要执行的语句,因此也被弹出 。没有更多代码可运行了 ,所以全局函数也从堆栈中删除 。
控制台输出“First”,“Third”,然后是“Second”。
很明显,libuv 用于处理 Node.js 中的异步操作。对于像处理网络请求这样的异步操作,libuv 依赖于操作系统原生机制。对于没有本地 OS 支持的异步读取文件的操作,libuv 则依赖其线程池以确保主线程不被阻塞。然而,这也引发了一些问题。
setTimeout
和 setInterval
这类延迟执行回调函数的方法又是何时执行回调函数呢?setTimeout
和 readFile
这类异步任务同时完成,Node 如何决定哪个回调函数先在调用栈上运行?其中一个会有更多的优先级吗?所有这些问题都可以通过理解 libuv 核心部分——事件循环来得到答案。
Secara teknikal, gelung acara hanyalah program C. Tetapi dalam Node.js, anda boleh menganggapnya sebagai corak reka bentuk untuk menyelaraskan pelaksanaan kod segerak dan tak segerak.
Gelung acara ialah gelung yang berjalan selagi aplikasi Node.js anda sedang berjalan. Terdapat enam baris gilir yang berbeza dalam setiap gelung, setiap satu mengandungi satu atau lebih fungsi panggil balik yang akhirnya perlu dilaksanakan pada tindanan panggilan.
setTimeout
dan setInterval
fungsi panggil balik yang berkaitan. fs
dan http
. setImmediate
, yang merupakan ciri khusus Nod. Akhir sekali, terdapat dua baris gilir berbeza membentuk baris gilir microtask. Baris gilir
process.nextTick
. Promise
setempat dalam JavaScript. Perlu diambil perhatian bahawa pemasa, I/O, semak dan tutup baris gilir semuanya milik libuv. Walau bagaimanapun, kedua-dua baris gilir microtask bukan milik libuv. Walau bagaimanapun, mereka masih memainkan peranan penting dalam persekitaran masa jalan Node dan memainkan peranan penting dalam susunan panggilan balik dilaksanakan. Setelah berkata demikian, mari kita fahami cara gelung acara berfungsi.
Anak panah dalam gambar adalah petunjuk, tetapi ia mungkin tidak mudah difahami. Biar saya terangkan susunan keutamaan baris gilir. Perkara pertama yang perlu diketahui ialah semua kod JavaScript segerak yang ditulis pengguna diutamakan daripada kod tak segerak. Ini bermakna gelung peristiwa hanya berfungsi apabila timbunan panggilan kosong.
Dalam gelung acara, susunan pelaksanaan mengikut peraturan tertentu. Masih terdapat beberapa peraturan yang perlu dikuasai Mari kita lihat satu persatu:
Pada masa ini, jika terdapat lebih banyak panggilan balik untuk diproses, gelung acara akan berjalan semula (Anotasi: Gelung acara terus berjalan semasa program sedang berjalan dan tiada tugas untuk diproses di Seterusnya, ia akan berada dalam keadaan menunggu dan akan dilaksanakan sebaik sahaja terdapat tugasan baharu) dan ulangi langkah yang sama. Sebaliknya, jika semua panggilan balik telah dilaksanakan dan tiada lagi kod untuk diproses, gelung acara akan keluar.
Inilah yang dilakukan oleh gelung peristiwa libuv untuk melaksanakan kod tak segerak dalam Node.js. Dengan peraturan ini di tangan, kami boleh menyemak semula soalan yang kami ajukan sebelum ini.
Apabila tugas tak segerak selesai dalam libuv, bilakah Node menjalankan fungsi panggil balik yang berkaitan pada tindanan panggilan?
Jawapan: Fungsi panggil balik hanya dilaksanakan apabila timbunan panggilan kosong.
Adakah Node akan menunggu timbunan panggilan kosong sebelum menjalankan fungsi panggil balik? Atau mengganggu aliran pelaksanaan biasa untuk menjalankan fungsi panggil balik?
Jawapan: Jalankan fungsi panggil balik tanpa mengganggu aliran biasa pelaksanaan.
Kaedah seperti setTimeout
dan setInterval
yang melambatkan pelaksanaan fungsi panggil balik, bilakah mereka melaksanakan fungsi panggil balik?
Jawapan: Keutamaan pertama antara semua fungsi panggil balik setTimeout
dan setInterval
dilaksanakan (tanpa mengira baris gilir microtask).
Jika dua tugas tak segerak (seperti setTimeout
dan readFile
) selesai pada masa yang sama, bagaimana Node menentukan fungsi panggil balik yang dilaksanakan dahulu dalam timbunan panggilan? Adakah satu akan mempunyai keutamaan yang lebih tinggi daripada yang lain?
Jawapan: Dalam kes penyiapan serentak, panggilan balik pemasa akan dilaksanakan sebelum panggilan balik I/O.
Banyak yang telah kami pelajari setakat ini, tetapi saya harap anda boleh mengingati urutan pelaksanaan yang ditunjukkan dalam gambar di bawah, kerana ia menunjukkan sepenuhnya perkara yang dilakukan Node.js di sebalik tabir. Bagaimana untuk melaksanakan kod tak segerak.
Tetapi, anda mungkin bertanya: "Di manakah kod untuk mengesahkan visualisasi ini?". Nah, setiap baris gilir dalam gelung acara mempunyai nuansa pelaksanaan, jadi lebih baik kita membincangkannya satu demi satu. Artikel ini ialah yang pertama dalam siri tentang gelung acara Node.js. Sila pastikan anda menyemak pautan di penghujung artikel untuk memahami butiran operasi dalam setiap baris gilir Walaupun anda mempunyai kesan mendalam dalam fikiran anda sekarang, anda mungkin masih terjebak apabila anda sampai ke senario tertentu. .
Panduan visual ini merangkumi asas pengaturcaraan tak segerak dalam JavaScript, masa jalan Node.js dan libuv, yang mengendalikan operasi tak segerak. Dengan pengetahuan ini, anda boleh membina model gelung peristiwa yang berkuasa yang akan mendapat manfaat apabila menulis kod yang mengambil kesempatan daripada sifat tak segerak Node.js.
Untuk lebih banyak pengetahuan berkaitan nod, sila lawati: tutorial nodejs!
Atas ialah kandungan terperinci Mari kita bincangkan tentang gelung acara dalam Node. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!