Rumah  >  Artikel  >  hujung hadapan web  >  Gelung Peristiwa

Gelung Peristiwa

WBOY
WBOYasal
2024-08-22 18:38:37491semak imbas

Event Loop

Pengenalan
JavaScript kebanyakannya dilaksanakan pada satu utas dalam Node.js dan dalam penyemak imbas (dengan beberapa pengecualian seperti utas pekerja, yang berada di luar skop artikel semasa). Dalam artikel ini, saya akan cuba menerangkan mekanisme konkurensi di Node.js iaitu Gelung Peristiwa.

Sebelum mula membaca artikel ini, anda harus biasa dengan tindanan dan cara ia berfungsi, saya pernah menulis tentang idea ini, jadi lihat Stack & Heap — Jangan mula mengekod tanpa memahaminya — Moshe Binieli | Sederhana

Imej Pengenalan
Contoh
Saya percaya bahawa pembelajaran adalah yang terbaik melalui contoh, oleh itu saya akan mulakan dengan 4 contoh kod mudah. Saya akan menganalisis contoh dan kemudian saya akan menyelami seni bina Node.js.

Contoh 1:
console.log(1);
console.log(2);
console.log(3);
// Output:
// 1
// 2
// 3
Contoh ini agak mudah, pada langkah pertama console.log(1) masuk ke dalam timbunan panggilan, sedang dilaksanakan dan kemudian dialih keluar, pada langkah kedua console.log(2) masuk ke dalam timbunan panggilan, sedang dilaksanakan dan kemudian dialih keluar, dan seterusnya untuk console.log(3).

Visualisasi timbunan panggilan untuk Contoh 1
Contoh 2:
console.log(1);
setTimeout(fungsi foo(){
console.log(2);
}, 0);
console.log(3);
// Output:
// 1
// 3
// 2
Kita dapat melihat dalam contoh ini bahawa kita menjalankan setTimeout serta-merta, jadi kita menjangkakan console.log(2) berada sebelum console.log(3), tetapi ini tidak berlaku dan mari kita fahami mekanisme di sebaliknya.

Seni Bina Gelung Acara Asas (Kami akan menyelami lebih lanjut kemudian)

Timbunan & Timbunan: Lihat artikel saya tentang yang ini (saya menambah pautan pada permulaan artikel ini)
Web Apis: Ia terbina dalam penyemak imbas web anda, dan dapat mendedahkan data daripada penyemak imbas dan persekitaran komputer di sekeliling serta melakukan perkara rumit yang berguna dengannya. Ia bukan sebahagian daripada bahasa JavaScript itu sendiri, sebaliknya ia dibina di atas bahasa JavaScript teras, memberikan anda kuasa besar tambahan untuk digunakan dalam kod JavaScript anda. Sebagai contoh, API Geolokasi menyediakan beberapa binaan JavaScript mudah untuk mendapatkan semula data lokasi supaya anda boleh berkata, plot lokasi anda pada Peta Google. Di latar belakang, penyemak imbas sebenarnya menggunakan beberapa kod peringkat rendah yang kompleks (cth. C++) untuk berkomunikasi dengan perkakasan GPS peranti (atau apa sahaja yang tersedia untuk menentukan data kedudukan), mendapatkan semula data kedudukan dan mengembalikannya ke persekitaran penyemak imbas untuk digunakan. dalam kod anda. Tetapi sekali lagi, kerumitan ini diasingkan daripada anda oleh API.
Gelung Peristiwa & Gilir Balik: Fungsi yang menamatkan pelaksanaan Web Apis sedang dialihkan ke Gilir Balik, ini ialah struktur data baris gilir biasa dan Gelung Acara bertanggungjawab untuk menyah gilir fungsi seterusnya daripada Giliran Panggilan Balik dan menghantar fungsi ke timbunan panggilan untuk melaksanakan fungsi.
Perintah pelaksanaan

Semua fungsi yang ada dalam tindanan panggilan pada masa ini dilaksanakan dan kemudiannya akan muncul daripada tindanan panggilan.
Apabila tindanan panggilan kosong, semua tugasan beratur akan muncul pada tindanan panggilan satu demi satu dan dilaksanakan, dan kemudian ia akan dikeluarkan dari tindanan panggilan.
Mari kita fahami contoh 2

kaedah console.log(1) dipanggil dan diletakkan pada timbunan panggilan dan sedang dilaksanakan.

  1. kaedah setTimeout dipanggil dan diletakkan pada timbunan panggilan dan sedang dilaksanakan, pelaksanaan ini mencipta panggilan baharu untuk setTimeout Web Api selama 0 milisaat, apabila ia selesai (segera, atau jika lebih tepat maka ia akan lebih baik menyebut “secepat mungkin”) Api Web mengalihkan panggilan ke Baris Gilir Panggilan Balik.

  2. kaedah console.log(3) dipanggil dan diletakkan pada timbunan panggilan dan sedang dilaksanakan.

  3. Gelung Peristiwa melihat bahawa Tindanan Panggilan kosong dan mengeluarkan kaedah "foo" daripada Baris Gilir Panggilan Balik dan meletakkannya dalam Tindanan Panggilan, kemudian console.log(2) sedang dilaksanakan.

Visualisasi proses untuk Contoh 2
Jadi parameter kelewatan dalam setTimeout(fungsi, kelewatan) tidak berdiri untuk kelewatan masa yang tepat selepas fungsi itu dilaksanakan. Ia bermaksud masa minimum untuk menunggu selepas itu pada satu masa tertentu fungsi akan dilaksanakan.

Contoh 3:
console.log(1);
setTimeout(fungsi foo() {
console.log(‘foo’);
}, 3500);
setTimeout(function boo() {
console.log(‘boo’);
}, 1000);
console.log(2);
// Output:
// 1
// 2
// 'boo'
// 'foo'

Visualisasi proses untuk Contoh 3
Contoh 4:
console.log(1);
setTimeout(fungsi foo() {
console.log(‘foo’);
}, 6500);
setTimeout(function boo() {
console.log(‘boo’);
}, 2500);
setTimeout(function baz() {
console.log(‘baz’);
}, 0);
untuk (nilai const [‘A’, ‘B’]) {
console.log(nilai);
}
fungsi dua() {
console.log(2);
}
dua();
// Output:
// 1
// 'A'
// 'B'
// 2
// 'baz'
// 'boo'
// 'foo'

Visualisasi proses untuk Contoh 4
Gelung acara meneruskan untuk melaksanakan semua panggilan balik yang menunggu dalam baris gilir tugas. Di dalam baris gilir tugasan, tugasan dikelaskan secara meluas kepada dua kategori, iaitu tugasan mikro dan tugasan makro.

Tugas Makro (Barisan Tugas) & Tugasan Mikro
Untuk lebih tepat sebenarnya terdapat dua jenis baris gilir.

  1. Baris gilir tugasan makro (atau baru dipanggil baris gilir tugas).
  2. Baris gilir tugas mikro.

Terdapat beberapa lagi tugasan yang masuk ke dalam baris gilir tugasan makro dan baris gilir tugas mikro tetapi saya akan menangani tugasan biasa.

Tugas Makro Biasa ialah setTimeout, setInterval dan setImmediate.
Tugas Mikro biasa ialah panggil balik process.nextTick dan Promise.
Perintah pelaksanaan
Semua fungsi yang berada dalam tindanan panggilan pada masa ini dilaksanakan dan kemudiannya akan muncul daripada tindanan panggilan.
Apabila timbunan panggilan kosong, semua tugasan mikro yang beratur akan dimunculkan pada timbunan panggilan satu demi satu dan dilaksanakan, dan kemudian ia dikeluarkan dari timbunan panggilan.
Apabila kedua-dua tindanan panggilan dan baris gilir tugas mikro kosong, semua tugasan makro yang beratur akan muncul pada tindanan panggilan satu demi satu dan dilaksanakan, dan kemudian ia akan dikeluarkan dari tindanan panggilan.
Contoh 5:
console.log(1);
setTimeout(fungsi foo() {
console.log(‘foo’);
}, 0);
Promise.resolve()
.then(function boo() {
console.log(‘boo’);
});
console.log(2);
// Output:
// 1
// 2
// 'boo'
// 'foo'
kaedah console.log(1) dipanggil dan diletakkan pada timbunan panggilan dan sedang dilaksanakan.
SetTimeout sedang dilaksanakan, console.log(‘foo’) dialihkan ke SetTimeout Web Api dan 0 milisaat selepas itu ia beralih ke Macro-Task Queue.
Promise.resolve() sedang dipanggil, ia sedang diselesaikan dan kemudian kaedah .then() dialihkan ke baris gilir Tugasan Mikro.
kaedah console.log(2) dipanggil dan diletakkan pada timbunan panggilan dan sedang dilaksanakan.
Gelung Peristiwa melihat bahawa tindanan panggilan kosong, ia mengambil pertama tugas daripada baris gilir Tugasan Mikro yang merupakan tugas Janji, meletakkan console.log(‘boo’) pada tindanan panggilan dan melaksanakannya.
Gelung Acara melihat bahawa tindanan panggilan kosong, kemudian ia melihat bahawa Tugasan Mikro kosong, kemudian ia mengambil tugas seterusnya daripada baris gilir Tugasan Makro yang merupakan tugas SetTimeout, meletakkan console.log('foo') pada timbunan panggilan dan laksanakannya.

Visualisasi proses untuk Contoh 5
Pemahaman lanjutan tentang Gelung Acara
Saya terfikir untuk menulis tentang tahap rendah cara mekanisme Gelung Acara berfungsi, ia boleh menjadi siaran itu sendiri, jadi saya memutuskan untuk membawa pengenalan kepada topik tersebut dan melampirkan pautan yang baik yang menerangkan topik itu secara mendalam.

Gelung Peristiwa peringkat bawah Diterangkan
Apabila Node.js bermula, ia memulakan gelung acara, memproses skrip input yang disediakan (atau jatuh ke dalam REPL) yang mungkin membuat panggilan API tak segerak, pemasa jadual atau proses panggilan.nextTick(), kemudian mula memproses gelung acara.

Rajah berikut menunjukkan gambaran ringkas tentang susunan operasi gelung peristiwa. (Setiap kotak akan dirujuk sebagai "fasa" gelung acara, sila lihat imej pengenalan untuk mendapatkan pemahaman yang baik tentang kitaran.)

Gambaran keseluruhan ringkas bagi susunan operasi gelung peristiwa
Setiap fasa mempunyai baris gilir panggilan balik FIFO untuk dilaksanakan (saya katakan dengan teliti di sini kerana mungkin terdapat struktur data lain bergantung pada pelaksanaan). Walaupun setiap fasa adalah istimewa dengan cara tersendiri, secara amnya, apabila gelung peristiwa memasuki fasa tertentu, ia akan melaksanakan sebarang operasi khusus untuk fasa tersebut, kemudian melaksanakan panggilan balik dalam baris gilir fasa tersebut sehingga baris gilir telah habis atau bilangan panggilan balik maksimum. telah dilaksanakan. Apabila baris gilir telah habis atau had panggil balik dicapai, gelung acara akan beralih ke fasa seterusnya dan seterusnya.

Gambaran Keseluruhan Fasa
Pemasa: fasa ini melaksanakan panggilan balik yang dijadualkan oleh setTimeout() dan setInterval().
Panggilan balik belum selesai: melaksanakan panggilan balik I/O ditangguhkan ke lelaran gelung seterusnya.
Terbiar, Sediakan: hanya digunakan secara dalaman.
Tinjauan: dapatkan semula acara I/O baharu; laksanakan panggilan balik berkaitan I/O (hampir semua kecuali panggilan balik tertutup, yang dijadualkan oleh pemasa, dan setImmediate()); nod akan menyekat di sini apabila sesuai.
Semak: setImmediate() panggilan balik digunakan di sini.
Tutup panggilan balik: beberapa panggilan balik rapat, mis. socket.on('tutup', ...).
Bagaimanakah langkah-langkah sebelumnya sesuai di sini?
Jadi langkah sebelumnya dengan hanya "Baris Gilir Panggilan Balik" dan kemudian dengan "Baris Gilir Makro dan Mikro" ialah penjelasan abstrak tentang cara Gelung Acara berfungsi.

Ada satu lagi perkara PENTING untuk disebut, gelung peristiwa harus memproses baris gilir tugas mikro sepenuhnya, selepas memproses satu tugasan makro daripada baris gilir tugasan makro.

Langkah 1: Gelung acara mengemas kini masa gelung kepada masa semasa untuk pelaksanaan semasa.
Langkah 2: Gilir Mikro dilaksanakan.
Langkah 3: Tugasan daripada fasa Pemasa dilaksanakan.
Langkah 4: Menyemak sama ada terdapat sesuatu dalam Micro-Queue dan melaksanakan keseluruhan Micro-Queue jika ada sesuatu.
Langkah 5: Kembali ke Langkah 3 sehingga fasa Pemasa kosong.
Langkah 6: Tugasan daripada fasa Panggilan Balik Menunggu dilaksanakan.
Langkah 7: Menyemak sama ada terdapat sesuatu dalam Gilir Mikro dan melaksanakan keseluruhan Gilir Mikro jika terdapat sesuatu.
Langkah 8: Kembali ke Langkah 6 sehingga fasa Panggilan Balik Menunggu kosong.
Dan kemudian Idle… Micro-Queue … Poll… Micro-Queue … Semak … Micro-Queue … Tutup Panggilan Balik dan kemudian ia bermula semula.
Jadi saya memberikan gambaran yang bagus tentang bagaimana Event Loop sebenarnya berfungsi di belakang tabir, terdapat banyak bahagian yang hilang yang saya tidak nyatakan di sini kerana dokumentasi sebenar melakukan kerja yang hebat dalam menerangkannya, saya akan menyediakan pautan yang hebat untuk dokumentasi, saya menggalakkan anda untuk melabur 10–20 minit dan memahaminya.

Atas ialah kandungan terperinci Gelung Peristiwa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn