Saya telah melewati panggilan balik atau hanya memicu fungsi dari fungsi lain dalam program saya untuk membuat sesuatu terjadi setelah tugas selesai. Ketika sesuatu selesai, saya langsung memicu fungsi:
var ground = 'clean';
function shovelSnow(){
console.log("Cleaning Snow");
ground = 'clean';
}
function makeItSnow(){
console.log("It's snowing");
ground = 'snowy';
shovelSnow();
}
Tapi saya sudah membaca tentang berbagai strategi dalam pemrograman, dan yang saya pahami kuat, tetapi belum dipraktikkan, berbasis event (saya pikir metode yang saya baca disebut "pub-sub" ):
var ground = 'clean';
function shovelSnow(){
console.log("Cleaning Snow");
ground = 'clean';
}
function makeItSnow(){
console.log("It's snowing");
ground = 'snowy';
$(document).trigger('snow');
}
$(document).bind('snow', shovelSnow);
Saya ingin memahami kekuatan dan kelemahan obyektif pemrograman berbasis acara, vs hanya memanggil semua fungsi Anda dari dalam fungsi lain. Dalam situasi pemrograman manakah pemrograman berbasis peristiwa masuk akal untuk digunakan?
event-programming
Viziionary
sumber
sumber
$(document).bind('snow', shovelShow)
. Tidak perlu membungkusnya dalam fungsi anonim.Jawaban:
Suatu acara adalah pemberitahuan yang menggambarkan kejadian dari masa lalu baru-baru ini.
Implementasi tipikal dari sistem yang digerakkan oleh event menggunakan fungsi dispatcher dan fungsi handler (atau pelanggan ). Dispatcher menyediakan API untuk mengirim penangan ke acara (jQuery's
bind
), dan metode untuk mempublikasikan acara kepada pelanggannya (trigger
di jQuery). Saat Anda berbicara tentang acara IO atau UI, biasanya juga ada loop acara , yang mendeteksi acara baru seperti klik mouse dan meneruskannya ke operator. Di JS-land, dispatcher dan loop acara disediakan oleh browser.Untuk kode yang berinteraksi langsung dengan pengguna - merespons penekanan tombol dan klik - pemrograman berdasarkan peristiwa (atau variasi daripadanya, seperti pemrograman reaktif fungsional ) hampir tidak dapat dihindari. Anda, sang programmer, tidak tahu kapan atau di mana pengguna akan mengklik, jadi tergantung pada kerangka kerja GUI atau browser untuk mendeteksi tindakan pengguna di loop acara dan memberi tahu kode Anda. Jenis infrastruktur ini juga digunakan dalam aplikasi jaringan (cf NodeJS).
Contoh Anda, di mana Anda meningkatkan suatu peristiwa dalam kode Anda daripada memanggil fungsi secara langsung memiliki beberapa tradeoff yang lebih menarik, yang akan saya bahas di bawah ini. Perbedaan utama adalah bahwa penerbit acara (
makeItSnow
) tidak menentukan penerima panggilan; yang terhubung di tempat lain (dalam panggilan kebind
dalam contoh Anda). Ini disebut api-dan-lupakan :makeItSnow
mengumumkan kepada dunia bahwa salju turun, tetapi tidak peduli siapa yang mendengarkan, apa yang terjadi selanjutnya, atau ketika itu terjadi - ia hanya menyiarkan pesan dan membersihkan debu dari tangannya.Jadi pendekatan event-driven decouples pengirim pesan dari penerima. Satu keuntungan yang bisa Anda dapatkan dari ini adalah bahwa suatu peristiwa tertentu mungkin memiliki banyak penangan. Anda dapat mengikat
gritRoads
fungsi ke acara salju Anda tanpa mempengaruhishovelSnow
penangan yang ada . Anda memiliki fleksibilitas dalam cara aplikasi Anda terhubung; untuk mematikan perilaku Anda hanya perlu menghapusbind
panggilan daripada pergi mencari kode untuk menemukan semua contoh perilaku.Keuntungan lain dari pemrograman berbasis acara adalah memberi Anda tempat untuk menaruh keprihatinan yang saling terkait. Dispatcher peristiwa memainkan peran Mediator , dan beberapa perpustakaan (seperti Brighter ) menggunakan pipa sehingga Anda dapat dengan mudah memasang persyaratan umum seperti logging atau kualitas layanan.
Pengungkapan penuh: Brighter dikembangkan di Huddle, tempat saya bekerja.
Keuntungan ketiga dari memisahkan pengirim dari suatu peristiwa dari penerima adalah memberi Anda keleluasaan ketika Anda menangani acara tersebut. Anda dapat memproses setiap jenis acara dengan utasnya sendiri (jika pengirim acara Anda mendukungnya), atau Anda dapat menempatkan acara yang ditinggikan ke pialang pesan seperti RabbitMQ dan menanganinya dengan proses asinkron atau bahkan memprosesnya dalam semalam massal. Penerima acara dapat dalam proses yang terpisah atau pada mesin yang terpisah. Anda tidak perlu mengubah kode yang memunculkan acara untuk melakukan ini! Ini adalah Ide Besar di balik arsitektur "layanan mikro": layanan otonom berkomunikasi menggunakan acara, dengan pesan middleware sebagai tulang punggung aplikasi.
Untuk contoh yang agak berbeda dari gaya yang digerakkan oleh peristiwa, lihat desain yang digerakkan oleh domain, tempat acara domain digunakan untuk membantu memisahkan agregat. Misalnya, pertimbangkan toko online yang merekomendasikan produk berdasarkan riwayat pembelian Anda. A
Customer
perlu memiliki riwayat pembelian yang diperbarui ketika aShoppingCart
dibayar. TheShoppingCart
agregat mungkin memberitahuCustomer
dengan mengangkatCheckoutCompleted
acara; ituCustomer
akan diperbarui dalam transaksi terpisah dalam menanggapi acara tersebut.Kelemahan utama dari model yang digerakkan oleh peristiwa ini adalah tipuan. Sekarang lebih sulit untuk menemukan kode yang menangani acara tersebut karena Anda tidak bisa menavigasi saja menggunakan IDE Anda; Anda harus mencari tahu di mana acara tersebut terikat dalam konfigurasi dan berharap bahwa Anda telah menemukan semua penangan. Masih ada banyak hal yang perlu diingat di suatu waktu. Konvensi gaya kode dapat membantu di sini (misalnya, meletakkan semua panggilan ke
bind
dalam satu file). Demi kewarasan Anda, penting untuk hanya menggunakan satu pengirim acara dan menggunakannya secara konsisten.Kerugian lain adalah sulit untuk memperbaiki acara. Jika Anda perlu mengubah format acara Anda juga harus mengubah semua penerima. Ini diperburuk ketika pelanggan suatu acara menggunakan mesin yang berbeda, karena sekarang Anda perlu menyinkronkan rilis perangkat lunak!
Dalam keadaan tertentu, kinerja dapat menjadi perhatian. Saat memproses pesan, operator harus:
Ini tentu saja lebih lambat daripada pemanggilan fungsi biasa, yang hanya melibatkan mendorong bingkai baru pada stack. Namun, fleksibilitas yang diberikan arsitektur event-driven membuat Anda lebih mudah untuk mengisolasi dan mengoptimalkan kode lambat. Memiliki kemampuan untuk mengirimkan pekerjaan ke prosesor asinkron adalah kemenangan besar di sini, karena memungkinkan Anda untuk melayani permintaan segera sementara kerja keras ditangani di latar belakang. Bagaimanapun, jika Anda berinteraksi dengan DB atau menggambar hal-hal di layar maka biaya IO benar-benar akan membebani biaya pemrosesan pesan. Ini adalah kasus menghindari optimasi prematur.
Singkatnya, acara adalah cara yang bagus untuk membangun perangkat lunak yang digabungkan secara longgar, tetapi bukan tanpa biaya. Ini akan menjadi kesalahan, misalnya, untuk mengganti setiap panggilan fungsi dalam aplikasi Anda dengan suatu peristiwa. Gunakan acara untuk membuat divisi arsitektur yang bermakna.
sumber
Pemrograman berbasis peristiwa digunakan ketika program tidak mengontrol urutan peristiwa yang dilakukan. Alih-alih, aliran program diarahkan oleh proses luar seperti pengguna (misalnya GUI), sistem lain (misalnya klien / server), atau proses lain (misalnya RPC).
Sebagai contoh, skrip pemrosesan batch tahu apa yang perlu dilakukan sehingga hanya melakukannya. Itu bukan berbasis acara.
Pengolah kata duduk di sana dan menunggu pengguna untuk mulai mengetik. Tekan tombol adalah peristiwa yang memicu fungsionalitas untuk memperbarui buffer dokumen internal. Program tidak dapat mengetahui apa yang ingin Anda ketikkan, sehingga harus didorong oleh peristiwa.
Sebagian besar program GUI dikendalikan oleh peristiwa karena dibuat berdasarkan interaksi pengguna. Namun, program berbasis acara tidak terbatas pada GUI, yang merupakan contoh paling umum bagi kebanyakan orang. Server web menunggu klien untuk terhubung dan mengikuti idiom serupa. Proses latar belakang pada komputer Anda juga dapat merespons acara. Misalnya, pemindai virus berdasarkan permintaan dapat menerima peristiwa dari OS terkait file yang baru dibuat atau diperbarui, kemudian memindai file tersebut dari virus.
sumber
Dalam aplikasi berbasis acara, konsep Pendengar Acara akan memberi Anda kemampuan untuk menulis aplikasi yang lebih longgar .
Misalnya modul pihak ketiga atau plug-in dapat menghapus catatan dari database dan kemudian memicu
receordDeleted
acara dan menyerahkan sisanya ke pendengar acara untuk melakukan pekerjaan mereka. Semuanya akan berfungsi dengan baik, meskipun modul pemicunya bahkan tidak tahu siapa yang mendengarkan acara khusus ini atau apa yang akan terjadi selanjutnya.sumber
Sebuah analogi sederhana yang ingin saya tambahkan yang membantu saya:
Pikirkan komponen (atau objek) aplikasi Anda sebagai grup besar teman-teman Facebook.
Ketika salah satu teman Anda ingin memberi tahu Anda sesuatu, mereka dapat menghubungi Anda secara langsung atau mempostingnya ke dinding Facebook mereka. Ketika mereka mempostingnya ke Facebook mereka, maka siapa pun dapat melihatnya dan bereaksi terhadapnya, tetapi banyak orang tidak melihatnya. Terkadang itu sesuatu yang penting yang orang mungkin perlu bereaksi terhadapnya, seperti "Kami akan punya bayi!" atau "Band ini sedang melakukan konser kejutan di bar Drunkin 'Clam!". Dalam kasus terakhir, maka teman-teman yang lain kemungkinan akan perlu bereaksi, terutama jika mereka tertarik pada band itu.
Jika teman Anda ingin menjaga rahasia antara Anda dan mereka, mereka mungkin tidak akan mempostingnya ke dinding Facebook mereka, mereka akan menghubungi Anda secara langsung dan memberi tahu Anda. Bayangkan sebuah skenario di mana Anda memberi tahu seorang gadis bahwa Anda ingin bertemu dengannya di sebuah restoran untuk kencan. Alih-alih memanggilnya langsung dan memintanya, Anda mempostingnya di dinding Facebook agar semua teman Anda dapat melihatnya. Ini bekerja, tetapi jika Anda memiliki mantan cemburu, maka dia bisa melihat itu dan muncul di restoran untuk merusak hari Anda.
Ketika memutuskan apakah akan membangun pendengar acara untuk mengimplementasikan sesuatu, pikirkan analogi ini. Apakah komponen ini perlu menempatkan bisnis mereka di luar sana agar dilihat oleh siapa pun? Atau apakah mereka perlu memanggil seseorang secara langsung? Hal-hal dapat menjadi sangat mudah berantakan jadi berhati-hatilah.
sumber
Analogi berikut ini dapat membantu Anda untuk memahami pemrograman I / O yang didorong oleh peristiwa dengan menggambar garis sejajar dengan garis tunggu di meja resepsionis Dokter.
Memblokir I / O seperti, jika Anda berdiri di antrian, resepsionis meminta seorang pria di depan Anda untuk mengisi formulir dan dia menunggu sampai selesai. Anda harus menunggu giliran Anda sampai orang itu menyelesaikan formulirnya, ini menghalangi.
Jika pria lajang membutuhkan waktu 3 menit untuk diisi, pria ke-10 harus menunggu hingga 30 menit. Sekarang untuk mengurangi 10 orang ini menunggu waktu, solusinya, meningkatkan jumlah resepsionis, yang mahal. Inilah yang terjadi di server web tradisional. Jika Anda meminta info pengguna, permintaan selanjutnya oleh pengguna lain harus menunggu sampai operasi saat ini, mengambil dari Database, selesai. Ini meningkatkan "waktu untuk menanggapi" dari permintaan ke-10 dan itu meningkat secara eksponensial untuk pengguna ke-n. Untuk menghindari hal ini, server web tradisional membuat utas (setara dengan peningkatan jumlah resepsionis) untuk setiap permintaan tunggal, mis., Pada dasarnya ia membuat salinan server untuk setiap permintaan yang merupakan interms mahal dari konsumsi CPU karena setiap permintaan akan membutuhkan sistem Operasi benang. Untuk meningkatkan aplikasi,
Didorong oleh Peristiwa : Pendekatan lain untuk meningkatkan "waktu respons" antrian adalah menggunakan pendekatan berdasarkan peristiwa, di mana orang yang ada dalam antrean akan menyerahkan formulir, diminta mengisi dan kembali setelah selesai. Karena itu resepsionis selalu dapat menerima permintaan. Inilah yang telah dilakukan javascript sejak awal. Di browser, javascript akan merespons acara klik pengguna, gulir, geser, atau ambil basis data, dan sebagainya. Ini dimungkinkan dalam javascript secara inheren, karena javascript memperlakukan fungsi sebagai objek kelas satu dan mereka dapat diteruskan sebagai parameter ke fungsi lain (disebut panggilan balik), dan dapat dipanggil saat menyelesaikan tugas tertentu. Inilah yang tepatnya dilakukan node.js di server. Anda dapat menemukan lebih banyak info tentang pemrograman yang digerakkan oleh acara dan memblokir i / o, dalam konteks simpul di sini
sumber