本文介绍了JavaScript编程设计模式之观察者模式(Observer Pattern),简单说明了观察者模式的概念、原理并结合实例形式详细给出了观察者模式的相关实现与使用技巧,需要的朋友可以参考下,希望能帮助到大家。
简介
简单的解释观察者模式,就是一个对象(subject)维护一个依赖他的对象(observers)列表,当自身状态发生变化时,自动通知所有观察者对象。当某个对象不需要获得通知时,可以从对象列表中删除掉。
从上面的解释中我们可以提炼出三个componet: Subject, ObserverList和Observer,用JS实现很简单:
function ObserverList(){ this.observerList = []; } ObserverList.prototype.Add = function( obj ){ return this.observerList.push( obj ); }; ObserverList.prototype.Empty = function(){ this.observerList = []; }; ObserverList.prototype.Count = function(){ return this.observerList.length; }; ObserverList.prototype.Get = function( index ){ if( index > -1 && index < this.observerList.length ){ return this.observerList[ index ]; } }; ObserverList.prototype.Insert = function( obj, index ){ var pointer = -1; if( index === 0 ){ this.observerList.unshift( obj ); pointer = index; }else if( index === this.observerList.length ){ this.observerList.push( obj ); pointer = index; } return pointer; }; ObserverList.prototype.IndexOf = function( obj, startIndex ){ var i = startIndex, pointer = -1; while( i < this.observerList.length ){ if( this.observerList[i] === obj ){ pointer = i; } i++; } return pointer; }; ObserverList.prototype.RemoveAt = function( index ){ if( index === 0 ){ this.observerList.shift(); }else if( index === this.observerList.length -1 ){ this.observerList.pop(); } }; // Extend an object with an extension function extend( extension, obj ){ for ( var key in extension ){ obj[key] = extension[key]; } }
Subject拥有增加和删除Observer的能力
function Subject(){ this.observers = new ObserverList(); } Subject.prototype.AddObserver = function( observer ){ this.observers.Add( observer ); }; Subject.prototype.RemoveObserver = function( observer ){ this.observers.RemoveAt( this.observers.IndexOf( observer, 0 ) ); }; Subject.prototype.Notify = function( context ){ var observerCount = this.observers.Count(); for(var i=0; i < observerCount; i++){ this.observers.Get(i).Update( context ); } };
最后定义一个观察者对象,实现update方法
// The Observer function Observer(){ this.Update = function(){ // ... }; }
当有多个观察者,只需扩展上面的基本对象,并重写Update方法。
尽管观察则模式被广泛使用,但在JS中经常使用它的变体: 发布订阅模式
发布订阅模式通过一个topic/event通道,解耦了观察者模式中Subject(发布者)和Observer(订阅者)之间耦合的问题,在JS中被广泛使用。
下面简单的例子说明了使用发布订阅模式的基本结构
// A very simple new mail handler // A count of the number of messages received var mailCounter = 0; // Initialize subscribers that will listen out for a topic // with the name "inbox/newMessage". // Render a preview of new messages var subscriber1 = subscribe( "inbox/newMessage", function( topic, data ) { // Log the topic for debugging purposes console.log( "A new message was received: ", topic ); // Use the data that was passed from our subject // to display a message preview to the user $( ".messageSender" ).html( data.sender ); $( ".messagePreview" ).html( data.body ); }); // Here's another subscriber using the same data to perform // a different task. // Update the counter displaying the number of new // messages received via the publisher var subscriber2 = subscribe( "inbox/newMessage", function( topic, data ) { $('.newMessageCounter').html( mailCounter++ ); }); publish( "inbox/newMessage", [{ sender:"hello@google.com", body: "Hey there! How are you doing today?" }]); // We could then at a later point unsubscribe our subscribers // from receiving any new topic notifications as follows: // unsubscribe( subscriber1, ); // unsubscribe( subscriber2 );
发布订阅模式的实现
许多Js库都很好的实现了发布订阅模式,例如Jquery的自定义事件功能。
// Publish // jQuery: $(obj).trigger("channel", [arg1, arg2, arg3]); $( el ).trigger( "/login", [{username:"test", userData:"test"}] ); // Dojo: dojo.publish("channel", [arg1, arg2, arg3] ); dojo.publish( "/login", [{username:"test", userData:"test"}] ); // YUI: el.publish("channel", [arg1, arg2, arg3]); el.publish( "/login", {username:"test", userData:"test"} ); // Subscribe // jQuery: $(obj).on( "channel", [data], fn ); $( el ).on( "/login", function( event ){...} ); // Dojo: dojo.subscribe( "channel", fn); var handle = dojo.subscribe( "/login", function(data){..} ); // YUI: el.on("channel", handler); el.on( "/login", function( data ){...} ); // Unsubscribe // jQuery: $(obj).off( "channel" ); $( el ).off( "/login" ); // Dojo: dojo.unsubscribe( handle ); dojo.unsubscribe( handle ); // YUI: el.detach("channel"); el.detach( "/login" );
简单实现
var pubsub = {}; (function(q) { var topics = {}, subUid = -1; // Publish or broadcast events of interest // with a specific topic name and arguments // such as the data to pass along q.publish = function( topic, args ) { if ( !topics[topic] ) { return false; } var subscribers = topics[topic], len = subscribers ? subscribers.length : 0; while (len--) { subscribers[len].func( topic, args ); } return this; }; // Subscribe to events of interest // with a specific topic name and a // callback function, to be executed // when the topic/event is observed q.subscribe = function( topic, func ) { if (!topics[topic]) { topics[topic] = []; } var token = ( ++subUid ).toString(); topics[topic].push({ token: token, func: func }); return token; }; // Unsubscribe from a specific // topic, based on a tokenized reference // to the subscription q.unsubscribe = function( token ) { for ( var m in topics ) { if ( topics[m] ) { for ( var i = 0, j = topics[m].length; i < j; i++ ) { if ( topics[m][i].token === token) { topics[m].splice( i, 1 ); return token; } } } } return this; }; }( pubsub ));
使用方法
// Another simple message handler // A simple message logger that logs any topics and data received through our // subscriber var messageLogger = function ( topics, data ) { console.log( "Logging: " + topics + ": " + data ); }; // Subscribers listen for topics they have subscribed to and // invoke a callback function (e.g messageLogger) once a new // notification is broadcast on that topic var subscription = pubsub.subscribe( "inbox/newMessage", messageLogger ); // Publishers are in charge of publishing topics or notifications of // interest to the application. e.g: pubsub.publish( "inbox/newMessage", "hello world!" ); // or pubsub.publish( "inbox/newMessage", ["test", "a", "b", "c"] ); // or pubsub.publish( "inbox/newMessage", { sender: "hello@google.com", body: "Hey again!" }); // We cab also unsubscribe if we no longer wish for our subscribers // to be notified // pubsub.unsubscribe( subscription ); // Once unsubscribed, this for example won't result in our // messageLogger being executed as the subscriber is // no longer listening pubsub.publish( "inbox/newMessage", "Hello! are you still there?" );
相关推荐:
Atas ialah kandungan terperinci JavaScript观察者模式实例详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Aplikasi JavaScript di dunia nyata termasuk pengaturcaraan sisi pelayan, pembangunan aplikasi mudah alih dan Internet of Things Control: 1. Pengaturcaraan sisi pelayan direalisasikan melalui node.js, sesuai untuk pemprosesan permintaan serentak yang tinggi. 2. Pembangunan aplikasi mudah alih dijalankan melalui reaktnatif dan menyokong penggunaan silang platform. 3. Digunakan untuk kawalan peranti IoT melalui Perpustakaan Johnny-Five, sesuai untuk interaksi perkakasan.

Saya membina aplikasi SaaS multi-penyewa berfungsi (aplikasi edTech) dengan alat teknologi harian anda dan anda boleh melakukan perkara yang sama. Pertama, apakah aplikasi SaaS multi-penyewa? Aplikasi SaaS Multi-penyewa membolehkan anda melayani beberapa pelanggan dari Sing

Artikel ini menunjukkan integrasi frontend dengan backend yang dijamin oleh permit, membina aplikasi edtech SaaS yang berfungsi menggunakan Next.Js. Frontend mengambil kebenaran pengguna untuk mengawal penglihatan UI dan memastikan permintaan API mematuhi dasar peranan

JavaScript adalah bahasa utama pembangunan web moden dan digunakan secara meluas untuk kepelbagaian dan fleksibiliti. 1) Pembangunan front-end: Membina laman web dinamik dan aplikasi satu halaman melalui operasi DOM dan kerangka moden (seperti React, Vue.js, sudut). 2) Pembangunan sisi pelayan: Node.js menggunakan model I/O yang tidak menyekat untuk mengendalikan aplikasi konkurensi tinggi dan masa nyata. 3) Pembangunan aplikasi mudah alih dan desktop: Pembangunan silang platform direalisasikan melalui reaktnatif dan elektron untuk meningkatkan kecekapan pembangunan.

Trend terkini dalam JavaScript termasuk kebangkitan TypeScript, populariti kerangka dan perpustakaan moden, dan penerapan webassembly. Prospek masa depan meliputi sistem jenis yang lebih berkuasa, pembangunan JavaScript, pengembangan kecerdasan buatan dan pembelajaran mesin, dan potensi pengkomputeran IoT dan kelebihan.

JavaScript adalah asas kepada pembangunan web moden, dan fungsi utamanya termasuk pengaturcaraan yang didorong oleh peristiwa, penjanaan kandungan dinamik dan pengaturcaraan tak segerak. 1) Pengaturcaraan yang didorong oleh peristiwa membolehkan laman web berubah secara dinamik mengikut operasi pengguna. 2) Penjanaan kandungan dinamik membolehkan kandungan halaman diselaraskan mengikut syarat. 3) Pengaturcaraan Asynchronous memastikan bahawa antara muka pengguna tidak disekat. JavaScript digunakan secara meluas dalam interaksi web, aplikasi satu halaman dan pembangunan sisi pelayan, sangat meningkatkan fleksibiliti pengalaman pengguna dan pembangunan silang platform.

Python lebih sesuai untuk sains data dan pembelajaran mesin, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python terkenal dengan sintaks ringkas dan ekosistem perpustakaan yang kaya, dan sesuai untuk analisis data dan pembangunan web. 2. JavaScript adalah teras pembangunan front-end. Node.js menyokong pengaturcaraan sisi pelayan dan sesuai untuk pembangunan stack penuh.

JavaScript tidak memerlukan pemasangan kerana ia sudah dibina dalam pelayar moden. Anda hanya memerlukan editor teks dan penyemak imbas untuk memulakan. 1) Dalam persekitaran penyemak imbas, jalankan dengan memasukkan fail HTML melalui tag. 2) Dalam persekitaran Node.js, selepas memuat turun dan memasang node.js, jalankan fail JavaScript melalui baris arahan.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Muat turun versi mac editor Atom
Editor sumber terbuka yang paling popular

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa

EditPlus versi Cina retak
Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.