Di Node, banyak objek memancarkan peristiwa. Misalnya, server TCP akan mengirimkan acara "Connect" setiap kali klien meminta koneksi, dan misalnya, setiap kali seluruh bagian data dibaca, sistem file akan mengirimkan acara "data". Objek -objek ini disebut event emitter di node. Acara pemancar memungkinkan programmer untuk berlangganan peristiwa yang menarik dan mengikat fungsi panggilan balik ke acara terkait, sehingga fungsi callback dipanggil setiap kali pemancar acara memancarkan suatu acara. Mode publikasi/berlangganan sangat mirip dengan mode GUI tradisional, seperti program akan menerima pemberitahuan yang sesuai ketika tombol diklik. Menggunakan model ini, program server dapat bereaksi ketika beberapa peristiwa terjadi, seperti koneksi klien, data yang tersedia di soket, atau file tertutup.
Anda juga dapat membuat pemancar acara Anda sendiri. Faktanya, Node menyediakan kelas semu Eventemitter khusus yang dapat digunakan sebagai kelas dasar untuk membuat pemancar acara Anda sendiri.
Memahami mode panggilan balik
Pemrograman asinkron tidak menggunakan nilai pengembalian fungsi untuk menunjukkan akhir dari panggilan fungsi, tetapi mengadopsi gaya pass berikutnya.
"Continuation-Passing Style" (CPS: Continuation-Passing Style) adalah gaya pemrograman, dan kontrol proses secara eksplisit diteruskan ke operasi berikutnya ...
Fungsi gaya CPS akan menerima fungsi sebagai parameter tambahan. Fungsi ini digunakan untuk secara eksplisit menunjukkan proses kontrol program berikutnya. Ketika fungsi CPS menghitung "nilai pengembalian", ia akan memanggil fungsi yang mewakili proses program berikutnya dan mengambil "nilai pengembalian" dari fungsi CPS sebagai parameternya.
Dari Wikipedia - http://en.wikipedia.org/wiki/continuation-passing_style
Dalam gaya pemrograman ini, setiap fungsi akan memanggil fungsi panggilan balik setelah eksekusi, sehingga program dapat terus berjalan. Anda akan mengerti nanti bahwa JavaScript sangat cocok untuk gaya pemrograman ini. Berikut adalah contoh memuat file ke dalam memori di bawah node:
Salinan kode adalah sebagai berikut:
var fs = membutuhkan ('fs');
fs.readfile ('/etc/passwd', function (err, filecontent) {
if (err) {
Lempar err;
}
console.log ('konten file', filecontent.toString ());
});
Dalam contoh ini, Anda melewati fungsi anonim inline sebagai parameter kedua Fs.readfile. Bahkan, ini menggunakan pemrograman CPS karena Anda menyerahkan proses eksekusi program berikutnya ke fungsi callback.
Seperti yang Anda lihat, parameter pertama dari fungsi callback adalah objek kesalahan. Jika kesalahan terjadi dalam program, parameter ini akan menjadi instance dari kelas kesalahan. Ini adalah pola umum untuk pemrograman CPS di simpul.
Pahami mode pemancar acara
Dalam mode panggilan balik standar, suatu fungsi dilewatkan sebagai parameter ke fungsi yang akan dieksekusi. Mode ini bekerja dengan sangat baik dalam skenario di mana klien perlu diberitahu setelah fungsi selesai. Namun, jika beberapa peristiwa terjadi selama pelaksanaan fungsi atau peristiwa terjadi beberapa kali, pola ini tidak cocok. Misalnya, jika Anda ingin diberi tahu setiap kali soket menerima data yang tersedia, Anda akan menemukan bahwa mode panggilan balik standar tidak terlalu berguna dalam skenario ini. Pada saat ini, mode pemancar acara berguna. Anda dapat menggunakan satu set antarmuka standar untuk memisahkan generator acara dan pendengar acara dengan jelas.
Saat menggunakan Mode Generator Acara, dua atau lebih objek terlibat - pemancar dan satu atau lebih pendengar acara.
Pemancar acara, seperti namanya, adalah objek yang dapat menghasilkan acara. Pendengar acara adalah kode yang terikat pada pemancar acara untuk mendengarkan jenis acara tertentu, seperti contoh berikut:
Salinan kode adalah sebagai berikut:
var req = http.Request (opsi, fungsi (respons) {
response.on ("data", function (data) {
console.log ("Beberapa data dari respons", data);
});
response.on ("end", function () {
Console.log ("Respons berakhir");
});
});
req.end ();
Kode ini menunjukkan dua langkah yang diperlukan saat membuat permintaan HTTP untuk mengakses server HTTP jarak jauh menggunakan API HTTP.Request Node (lihat bab selanjutnya). Baris pertama mengadopsi "gaya lanjutan lanjutan" (CPS: Continuation-Passing Style), melewati fungsi inline yang akan disebut ketika HTTP merespons. API Permintaan HTTP menggunakan CPS di sini karena program perlu terus melakukan operasi selanjutnya setelah fungsi HTTP.Request dijalankan.
Ketika http.Request dieksekusi, fungsi panggilan balik anonim akan dipanggil, dan objek respons HTTP diteruskan ke sana sebagai parameter. Objek respons HTTP ini adalah pemancar acara. Menurut dokumen Node, dapat memancarkan banyak peristiwa termasuk data dan akhir. Fungsi panggilan balik yang Anda daftarkan akan dipanggil setiap kali acara terjadi.
Sebagai pelajaran, gunakan mode CPS ketika Anda perlu mendapatkan kembali hak eksekusi setelah operasi yang diminta selesai, dan gunakan mode pemancar acara ketika peristiwa dapat terjadi beberapa kali.
Memahami jenis acara
Acara yang ditransmisikan memiliki jenis yang diwakili oleh string. Contoh sebelumnya berisi dua jenis peristiwa: "data" dan "end", yang merupakan string yang ditentukan oleh pemancar peristiwa. Namun, secara konvensional konstitutif bahwa jenis peristiwa biasanya terdiri dari kata -kata kecil yang tidak mengandung karakter kosong.
Anda tidak dapat menggunakan kode untuk menyimpulkan jenis peristiwa apa yang dapat dihasilkan oleh pemancar peristiwa, karena API pemancar acara tidak memiliki mekanisme introspeksi, sehingga API yang Anda gunakan harus memiliki dokumentasi untuk menunjukkan bahwa ia dapat memancarkan jenis peristiwa tersebut.
Setelah suatu peristiwa terjadi, pemancar acara akan menghubungi pendengar yang terkait dengan acara tersebut dan meneruskan data yang relevan kepada pendengar sebagai parameter. Dalam contoh sebelumnya http.request, fungsi callback "data" menerima objek data sebagai parameter pertama dan satu -satunya, sementara "end" tidak menerima data apa pun. Parameter ini sebagai bagian dari kontrak API juga secara subyektif ditentukan oleh penulis API. Tanda tangan parameter dari fungsi panggilan balik ini juga akan dijelaskan dalam dokumentasi API dari masing -masing pemancar acara.
Meskipun pemancar acara adalah antarmuka yang melayani semua jenis acara, acara "Kesalahan" adalah implementasi khusus di Node. Sebagian besar pemancar peristiwa dalam node akan menghasilkan peristiwa "kesalahan" ketika kesalahan terjadi dalam program. Jika program tidak mendengarkan peristiwa "kesalahan" dari pemancar acara, pemancar acara akan melihat dan melemparkan pengecualian yang tidak tertahan saat kesalahan terjadi.
Anda dapat menjalankan kode berikut di Node Perl untuk menguji efeknya, yang mensimulasikan pemancar peristiwa yang dapat menghasilkan dua peristiwa:
Salinan kode adalah sebagai berikut:
var em = baru (membutuhkan ('acara'). Eventemitter) ();
em.emit ('event1');
em.emit ('error', kesalahan baru ('kesalahan saya'));
Anda akan melihat output berikut:
Salinan kode adalah sebagai berikut:
var em = baru (membutuhkan ('acara'). Eventemitter) ();
belum diartikan
> em.emit ('event1');
PALSU
> em.emit ('error', kesalahan baru ('kesalahan saya'));
Kesalahan: Kesalahan saya
di repl: 1: 18
di ReplServer.eval (repl.js: 80: 21)
di repl.js: 190: 20
AT REPLSERVER.EVAL (REPL.JS: 87: 5)
di antarmuka. <Anonymous> (repl.js: 182: 12)
di antarmuka.emit (events.js: 67: 17)
di antarmuka._online (readline.js: 162: 10)
di antarmuka._line (readline.js: 426: 8)
di antarmuka._ttywrite (readline.js: 603: 14)
di readStream. <Anonymous> (readline.js: 82: 12)
>
Dalam baris 2 kode, sebuah peristiwa yang disebut "event1" dipancarkan, tanpa efek apa pun, tetapi ketika peristiwa "kesalahan" dipancarkan, kesalahan dilemparkan ke tumpukan. Jika program tidak berjalan di lingkungan jalur perintah Perl, program akan macet karena pengecualian yang tidak tertutup.
Menggunakan API Pemancar Acara
Objek apa pun yang mengimplementasikan mode pemancar peristiwa (seperti soket TCP, permintaan HTTP, dll.) Mengimplementasikan serangkaian metode berikut:
Salinan kode adalah sebagai berikut:
.addlistener dan .on - tambahkan pendengar acara untuk acara dari jenis yang ditentukan
.once - ikat pendengar acara yang hanya dieksekusi sekali untuk peristiwa jenis yang ditentukan
.RemoveEventListener - Hapus pendengar yang terikat pada acara yang ditentukan
.removeallleventListener - hapus semua pendengar terikat pada acara yang ditentukan
Mari kita perkenalkan secara rinci di bawah ini.
Mengikat fungsi panggilan balik menggunakan .addlistener () atau .on ()
Dengan menentukan jenis acara dan fungsi panggilan balik, Anda dapat mendaftarkan tindakan yang dilakukan saat peristiwa terjadi. Misalnya, jika ada blok data yang tersedia ketika file membaca aliran data, itu akan memancarkan peristiwa "data". Kode berikut menunjukkan cara lulus fungsi panggilan balik untuk membiarkan program memberi tahu Anda bahwa peristiwa data telah terjadi.
Salinan kode adalah sebagai berikut:
fungsi diterima (data) {
console.log ("Dapatkan data dari arsip baca aliran: %j", data);
}
readStream.addlistener ("data", receptata);
Anda juga dapat menggunakan .on, yang hanya singkatan dari .addlistener. Kode berikut sama dengan yang di atas:
Salinan kode adalah sebagai berikut:
fungsi diterima (data) {
console.log ("Dapatkan data dari arsip baca aliran: %j", data);
}
readStream.on ("Data", Receptata);
Dalam kode sebelumnya, Anda dapat menggunakan fungsi bernama yang ditentukan sebelumnya sebagai fungsi callback, dan Anda juga dapat menggunakan fungsi anonim sebaris untuk menyederhanakan kode:
Salinan kode adalah sebagai berikut:
readStream.on ("data", function (data) {
console.log ("Dapatkan data dari arsip baca aliran: %j", data);
});
Seperti yang disebutkan sebelumnya, jumlah parameter dan tanda tangan yang diteruskan ke fungsi callback tergantung pada objek pemancar peristiwa tertentu dan jenis peristiwa. Mereka tidak standar. Acara "Data" dapat melewati objek penyangga data, acara "Kesalahan" melewati objek kesalahan, dan peristiwa "akhir" dari aliran data tidak memberikan data apa pun kepada pendengar acara.
Mengikat beberapa pendengar acara
Mode pemancar acara memungkinkan beberapa pendengar acara mendengarkan jenis acara yang sama dari pemancar acara yang sama, seperti:
Salinan kode adalah sebagai berikut:
Saya punya beberapa data di sini.
Saya memiliki beberapa data di sini juga.
Pemancar acara bertanggung jawab untuk memohon semua pendengar yang terikat pada jenis acara yang ditentukan dalam urutan di mana pendengar terdaftar, yaitu:
1. Ketika suatu peristiwa terjadi, pendengar acara mungkin tidak akan segera dipanggil, dan mungkin ada pendengar acara lain yang disebut sebelumnya.
2. Tidak normal untuk dilemparkan ke tumpukan, yang mungkin karena bug dalam kode. Ketika suatu acara ditransmisikan, jika pendengar acara melempar pengecualian ketika disebut, beberapa pendengar acara mungkin tidak pernah dipanggil. Dalam hal ini, pemancar acara menangkap pengecualian dan juga dapat menanganinya.
Lihat contoh berikut:
Salinan kode adalah sebagai berikut:
readStream.on ("data", function (data) {
Lemparkan kesalahan baru ("Sesuatu yang salah telah terjadi");
});
readStream.on ("data", function (data) {
Console.log ('Saya punya beberapa data di sini juga.');
});
Karena pendengar pertama melempar pengecualian, pendengar kedua tidak akan dipanggil.
Gunakan .removelistener () untuk menghapus pendengar acara dari pemancar acara
Jika Anda tidak lagi peduli tentang suatu acara pada suatu objek, Anda dapat membatalkan pendengar acara terdaftar dengan menentukan jenis acara dan fungsi panggilan balik, seperti ini:
Salinan kode adalah sebagai berikut:
fungsi diterima (data) {
console.log ("Dapatkan data dari arsip baca aliran: %j", data);
}
readStream.on ("Data", Receptata);
// ...
readStream.removelistener ("data", recequata);
Dalam contoh ini, baris terakhir menghapus pendengar acara yang dapat dipanggil kapan saja di masa depan dari objek pemancar acara.
Untuk menghapus pendengar, Anda harus memberi nama fungsi panggilan balik, karena nama fungsi callback diperlukan saat menambahkan dan menghapusnya.
Gunakan .once () untuk mengaktifkan fungsi callback paling banyak dieksekusi
Jika Anda ingin mendengarkan acara yang paling banyak dijalankan sekali, atau hanya tertarik pada pertama kalinya suatu peristiwa terjadi, Anda dapat menggunakan fungsi .once ():
Salinan kode adalah sebagai berikut:
fungsi diterima (data) {
console.log ("Dapatkan data dari arsip baca aliran: %j", data);
}
readStream.once ("Data", Receptata);
Dalam kode di atas, fungsi yang diterima hanya akan dipanggil sekali. Jika objek ReadStream memancarkan acara data, fungsi panggilan balik yang diterima akan dan hanya akan dipicu sekali.
Ini sebenarnya hanya metode yang nyaman, karena dapat diimplementasikan dengan sangat sederhana, seperti ini:
Salinan kode adalah sebagai berikut:
var eventemitter = membutuhkan ("acara"). Eventemitter;
EventeMitter.Prototype.once = function (type, callback) {
var itu = ini;
this.on (type, function listener () {
itu.removelistener (ketik, pendengar);
callback.Apply (itu, argumen);
});
};
Dalam kode di atas, Anda mendefinisikan kembali fungsi EventeMitter.prototype.onc, dan juga mendefinisikan kembali fungsi sekali dari setiap objek yang diwarisi dari EventeMitter. Kode hanya menggunakan metode .on (). Setelah acara diterima, gunakan .RemoveEventListener () untuk membatalkan pendaftaran fungsi callback dan hubungi fungsi callback asli.
CATATAN: Kode sebelumnya menggunakan metode fungsi.apply (), yang menerima objek dan menganggapnya sebagai variabel ini dan array parameter. Dalam contoh sebelumnya, array parameter yang tidak dimodifikasi secara transparan diteruskan ke fungsi callback melalui pemancar acara.
Hapus semua pendengar acara dari pemancar acara dengan .removealllisteners ()
Anda dapat menghapus semua pendengar yang terdaftar ke jenis acara yang ditentukan dari pemancar acara sebagai berikut:
Salinan kode adalah sebagai berikut:
emitter.removealllisteners (tipe);
Misalnya, Anda dapat membatalkan pendengar semua sinyal interupsi proses seperti ini:
Salinan kode adalah sebagai berikut:
Process.removealllisteners ("sigterm");
Catatan: Sebagai pelajaran, disarankan agar Anda hanya menggunakan fungsi ini ketika Anda tahu persis apa yang dihapus. Jika tidak, Anda harus membiarkan bagian lain dari aplikasi menghapus koleksi pendengar acara, atau Anda juga dapat membiarkan bagian -bagian dari program tersebut bertanggung jawab untuk menghapus pendengar itu sendiri. Tetapi apa pun yang terjadi, fungsi ini masih berguna dalam beberapa skenario langka, seperti ketika Anda bersiap untuk menutup pemancar acara atau mematikan seluruh proses dengan cara yang tertib.
Buat pemancar acara
Pemancar acara membuat antarmuka pemrograman lebih umum dengan cara yang bagus. Dalam mode pemrograman yang umum dan mudah dipahami, klien secara langsung memanggil berbagai fungsi, saat dalam mode pemancar acara, klien terikat pada berbagai acara, yang akan membuat program Anda lebih fleksibel. (Catatan Penerjemah: Kalimat ini tidak terlalu percaya diri, memposting teks asli: Emitter acara memberikan cara yang bagus untuk membuat antarmuka pemrograman lebih umum. Saat Anda menggunakan pola pemahaman umum, klien berikatan dengan acara alih -alih memohon fungsi, membuat program Anda lebih fleksibel.)
Selain itu, dengan menggunakan pemancar acara, Anda juga dapat memperoleh banyak fitur, seperti mengikat beberapa pendengar yang tidak terkait di acara yang sama.
Diwarisi dari pemancar acara simpul
Jika Anda tertarik dengan mode emitor acara Node dan bermaksud menggunakannya di aplikasi Anda sendiri, Anda dapat membuat kelas semu dengan mewarisi Eventemitter:
Salinan kode adalah sebagai berikut:
util = membutuhkan ('util');
var eventemitter = membutuhkan ('acara'). Eventemitter;
// Ini adalah konstruktor myclass:
var myclass = function () {
}
util.inherit (myclass, eventemitter);
Catatan: Util.inhits membuat rantai prototipe myClass, sehingga instance myclass Anda dapat menggunakan metode prototipe Eventemitter.
Luncurkan acara
Dengan mewarisi dari Eventemitter, MyClass dapat meluncurkan acara seperti ini:
Salinan kode adalah sebagai berikut:
Myclass.prototype.somemethod = function () {
this.emit ("acara khusus", "argumen 1", "argumen 2");
};
Dalam kode di atas, ketika metode somemethond dipanggil oleh MyClass, sebuah peristiwa yang disebut "acara lucu" akan dipancarkan. Acara ini juga akan memancarkan dua string sebagai data: "Argumen 1" dan "Argumen 2", yang akan disahkan sebagai parameter untuk pendengar acara.
Klien dari instance MyClass dapat mendengarkan acara "acara khusus" seperti ini:
Salinan kode adalah sebagai berikut:
var myInstance = myclass baru ();
myInstance.on ('custom event', function (str1, str2) {
Console.log ('Mendapat acara khusus dengan STR1 %S dan STR2 %S!', STR1, STR2);
});
Misalnya, Anda dapat membuat kelas ticker yang memancarkan acara "Tick" sekali:
Salinan kode adalah sebagai berikut:
var util = membutuhkan ('util'),
Eventemitter = membutuhkan ('acara'). Eventemitter;
var ticker = function () {
var self = ini;
setInterval (function () {
self.emit ('centang');
}, 1000);
};
util.inherite (ticker, eventemitter);
Klien yang menggunakan kelas ticker dapat menunjukkan cara menggunakan kelas ticker dan mendengarkan acara "centang".
Salinan kode adalah sebagai berikut:
var ticker = ticker baru ();
ticker.on ("tick", function () {
console.log ("centang");
});
ringkasan
Mode pemancar peristiwa adalah pola reentrance yang dapat digunakan untuk memisahkan objek pemancar peristiwa dari satu set kode untuk acara tertentu.
Anda dapat menggunakan Event_emitter.on () untuk mendaftarkan pendengar untuk jenis acara tertentu dan tidak terdaftar dengan Event_emitter.removelistener ().
Anda juga dapat membuat emitor acara Anda sendiri dengan mewarisi Eventemitter dan hanya menggunakan fungsi .emit ().