Rumah  >  Artikel  >  hujung hadapan web  >  Node.js event driven_node.js

Node.js event driven_node.js

WBOY
WBOYasal
2016-05-16 15:54:071267semak imbas

Ikhtisar pelaksanaan Node.js dipacu peristiwa

Walaupun "peristiwa" tidak (dan tidak perlu) ditakrifkan dengan jelas dalam standard ECMAScript, peristiwa berfungsi sebagai mekanisme yang sangat penting dalam penyemak imbas, memberikan JavaScript keupayaan untuk bertindak balas terhadap operasi pengguna dan perubahan DOM dalam Node , model dipacu peristiwa tak segerak adalah asas kepada keupayaan konkurensi yang tinggi.

Pembelajaran JavaScript juga memerlukan pemahaman platform berjalannya Untuk lebih memahami model acara JavaScript, saya bercadang untuk memulakan dengan Node dan kod sumber enjin penyemak imbas, menganalisis pelaksanaan asasnya dan menyusun analisis saya ke dalam satu siri catatan blog. ; Di satu pihak, ia adalah nota, dan di sisi lain, saya berharap untuk berkomunikasi dengan semua orang jika terdapat sebarang kekurangan dan berat sebelah dalam analisis dan pemahaman, saya harap anda akan membetulkan saya.

Penerangan ringkas tentang model dipacu peristiwa

Sudah ada banyak artikel bagus yang menerangkan model acara JavaScript itu sendiri. Boleh dikatakan ini sudah menjadi topik yang kurang dibincangkan Di sini saya hanya akan menulis secara ringkas dan memberikan pautan kepada beberapa artikel yang bagus.

Cara program bertindak balas terhadap acara

Program kami bertindak balas kepada acara luaran dalam dua cara berikut:

Gangguan

Sistem pengendalian mengendalikan papan kekunci dan input perkakasan lain melalui gangguan Kelebihan kaedah ini ialah walaupun tanpa berbilang benang, kami boleh melaksanakan kod kami dengan selamat Selepas CPU menerima isyarat gangguan, ia akan secara automatik melaksanakan sepadan Selepas pengendali sampukan selesai, persekitaran pelaksanaan kod asal akan dipulihkan dan pelaksanaan akan diteruskan. Kaedah ini memerlukan sokongan perkakasan dan biasanya dirangkumkan oleh sistem pengendalian.

Pengundian

Gelung untuk mengesan sama ada peristiwa berlaku, dan jika ya, laksanakan pengendali yang sepadan. Ini terpakai kepada pembangunan peringkat rendah dan atas.
Program tetingkap Windows perlu menulis kod berikut dalam utas utama, biasanya dipanggil gelung mesej:

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

Gelung mesej secara berterusan mengesan sama ada terdapat mesej (operasi UI pengguna, mesej sistem, dll. Jika ya, ia mengedarkan mesej dan memanggil fungsi panggil balik yang sepadan untuk pemprosesan).
Satu kelemahan kaedah pengundian ialah jika operasi yang memakan masa dilakukan dalam gelung mesej utas utama, program tidak dapat bertindak balas kepada mesej baharu tepat pada masanya. Ini jelas dalam JavaScript dan akan disebut kemudian, bersama-sama dengan penyelesaiannya.

Walau bagaimanapun, tiada kod gelung mesej yang serupa dalam JavaScript Kami hanya mendaftarkan acara dan menunggu untuk dipanggil. Ini kerana penyemak imbas dan Node, sebagai platform pelaksanaan, telah melaksanakan kod JavaScript tidak perlu terlibat dalam proses ini. Ia hanya perlu menunggu dengan senyap sebagai penerima.

Gelung peristiwa dalam Nod

Lihat pelaksanaan gelung acara melalui kod sumber Nod

Node menggunakan V8 sebagai enjin pelaksanaan JavaScript dan menggunakan libuv untuk melaksanakan I/O tak segerak dipacu peristiwa. Gelung acaranya menggunakan gelung acara lalai libuv.

Dalam src/node.cc,

Environment* env = CreateEnvironment(
    node_isolate,
    uv_default_loop(),
    context,
    argc,
    argv,
    exec_argc,
    exec_argv);

Kod ini mewujudkan persekitaran pelaksanaan nod Anda boleh melihat uv_default_loop() dalam baris ketiga Ini ialah fungsi dalam pustaka libuv itu sendiri dan default_loop_struct di dalamnya. Penunjuk default_loop_ptr.
Selepas itu, Node akan memuatkan persekitaran pelaksanaan dan menyelesaikan beberapa operasi persediaan, dan kemudian memulakan gelung acara:

bool more;
do {
 more = uv_run(env->event_loop(), UV_RUN_ONCE);
 if (more == false) {
  EmitBeforeExit(env);
  // Emit `beforeExit` if the loop became alive either after emitting
  // event, or after running some callbacks.
  more = uv_loop_alive(env->event_loop());
  if (uv_run(env->event_loop(), UV_RUN_NOWAIT) != 0)
   more = true;
 }
} while (more == true);
code = EmitExit(env);
RunAtExit(env);
...

lebih banyak digunakan untuk mengenal pasti sama ada untuk meneruskan ke kitaran seterusnya.

env->event_loop() akan mengembalikan default_loop_ptr yang disimpan sebelum ini dalam env, dan fungsi uv_run akan memulakan gelung acara libuv dalam mod UV_RUN_ONCE yang ditentukan. Dalam mod ini, uv_run akan memproses sekurang-kurangnya satu peristiwa: ini bermakna jika tiada peristiwa I/O yang perlu diproses dalam baris gilir acara semasa, uv_run akan menyekat sehingga terdapat peristiwa I/O yang perlu diproses , atau pemasa seterusnya Masa tamat. Jika pada masa ini tiada acara I/O dan tiada acara pemasa, uv_run mengembalikan palsu.

Nod Seterusnya akan memutuskan langkah seterusnya berdasarkan situasi lebih banyak:

Jika lebih banyak adalah benar, teruskan jalankan gelung seterusnya.

Jika lebih banyak adalah palsu, ini bermakna tiada peristiwa yang menunggu untuk diproses EmitBeforeExit(env); selepas selesai.

Akhir sekali, peristiwa 'keluar' dicetuskan, fungsi panggil balik yang sepadan dilaksanakan, operasi Nod tamat dan beberapa operasi keluaran sumber akan dilakukan kemudian.

Dalam libuv, acara pemasa diproses terus dalam gelung acara, manakala acara I/O dibahagikan kepada dua kategori:

I/O Rangkaian menggunakan penyelesaian I/O tidak menyekat yang disediakan oleh sistem, seperti epoll pada Linux dan IOCP pada Windows.

Tiada penyelesaian sistem (baik) untuk operasi fail dan operasi DNS, jadi libuv membina kumpulan benangnya sendiri untuk melakukan penyekatan I/O.

Selain itu, kami juga boleh membuang fungsi tersuai ke dalam kumpulan utas untuk dijalankan Selepas operasi selesai, utas utama akan melaksanakan fungsi panggil balik yang sepadan Walau bagaimanapun, Node tidak menambahkan fungsi ini pada JavaScript, yang bermaksud itu Ia hanya mustahil untuk membuka utas baharu dalam JavaScript untuk pelaksanaan selari menggunakan Node asli.

Di atas adalah keseluruhan kandungan artikel ini, saya harap anda semua menyukainya.

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