Heim > Artikel > Web-Frontend > Detaillierte Einführung in das Beobachtermuster von JavaScript-Entwurfsmustern
Javascript ist in einer ereignisgesteuerten Umgebung aktiv, z. B. bei Mausreaktionen, Ereignisrückrufen, Netzwerkanforderungen usw. Der 观察者
-Modus, auch bekannt als 发布者-订阅者(publisher-subscriber)模式
, verwaltet die Beziehung zwischen Objekten, deren Verhalten und Zuständen. und verwaltet die Beziehung zwischen Menschen und Aufgaben.
document.body.addEventListener('click', function () { console.log('you clicked me, poor guy!') });
Dies ist das einfachste und häufigste Beobachtermuster, außer click
Zusätzlich zu load
, blur
, drag
, focus
, mouseover
usw. Ein Ereignis-Listener (Listener) unterscheidet sich von einem Ereignis-Handler (Handler). Bei einem Ereignis-Listener kann ein Ereignis mehreren Listenern zugeordnet werden, und jeder Listener ist für die Ausführung und Verarbeitung des Ereignisses verantwortlich . Nach der zugehörigen Funktion kann ein Ereignis eine Handlerfunktion haben:
var dom = $('.dom'); var listener1 = function(e){ //do one thing } var listener2 = function(e){ //do another thing } addEvent(dom,'click',listener1); addEvent(dom,'click',listener2);
In diesem Beispiel eines Ereignis-Listeners sind sowohl listener1
als auch listener2
Listener für dom-Elemente. ihre jeweiligen Funktionen werden ausgeführt;
var dom = document.getElementById('dom'); var handler1 = function(e){ //do one thing } var handler2 = function(e){ //do another thing } dom.onclick = handler1; dom.onclick = handler2;
Im Beispiel dieses Ereignishandlers wird handler1
nicht ausgeführt, sondern nur handler2
, was eine Zuweisungsoperation ist.
Der Beobachtermodus wird häufig in der Animation verwendet. Der Beginn, der Abschluss, die Pause usw. der Animation erfordern, dass ein Beobachter das Verhalten und den Status des Objekts bestimmt.
//定义动画 var Animation = function(){ this.onStart = new Publisher; //关于Publisher的设计将在1.3节介绍 this.onComplete = new Publisher; this.onTween = new Publisher; } //定义一个原型方法 Animation.prototype.look = function(){ this.onStart.deliver('animation started!'); this.onTween.deliver('animation is going on!'); this.onComplete.deliver('animation completed!'); }; //实例一个box对象 var box = new Animation(); //定义三个函数作为subscribers var openBox = function(msg){ console.log(msg) } var checkBox = function(msg){ console.log(msg) } var closeBox = function(msg){ console.log(msg) } //订阅事件 openBox.subscribe(box.onStart); checkBox.subscribe(box.onTween); closeBox.subscribe(box.onComplete); //调用方法 box.look() //animation started! //animation is going on! //animation completed!
Zuerst wird ein Herausgeber benötigt. Definieren Sie zunächst einen Konstruktor und ein Array zum Speichern von Abonnenteninformationen:
function Publisher(){ this.subscribes = []; }
Der Herausgeber hat die Funktion, Nachrichten zu veröffentlichen, und definiert eine Prototypfunktion für die Zustellung:
Publisher.prototype.deliver = function(data){ this.subscribes.forEach(function(fn){ fn(data); }); return this; }
Nächster Erstellen Sie die Abonnementmethode:
Function.prototype.subscribe = function(publisher){ var that = this; var alreadyExists = publisher.subscribes.some(function(el){ return el === that; }); if(!alreadyExists){ publisher.subscribes.push(this); } return this; }
Fügen Sie die Abonnementmethode direkt zum Funktionsprototyp hinzu, damit alle Funktionen diese Methode aufrufen können. Auf diese Weise ist die Konstruktion abgeschlossen. Informationen zu den Verwendungsmethoden finden Sie im Anwendungsfall von 1.2 Animation.
Eine intuitivere Erklärung (nehmen Sie onStart
als Beispiel): Wenn das box
-Objekt die look
-Methode ausführt, führen Sie onStart.deliver()
aus, veröffentlichen Sie das onStart
-Ereignis und senden Sie es Benachrichtigung'animation started!'
, zu diesem Zeitpunkt hört onStart
, der openBox
abgehört hat, die durch das Ereignis veröffentlichten Informationen ab und druckt sie aus.
Diese Methode imitiert den Ereignisverarbeitungsmechanismus von NodeJS und der Code ist relativ prägnant:
var scope = (function() { //消息列表 var events = {}; return { //订阅消息 on:function(name,hander){ var index = 0; //记录消息时间的索引 if(events[name]){ //消息名已存在,将处理函数放到该消息的事件队列中 index = events[name].push(hander) - 1; }else{ events[name] = [hander]; } //返回当前消息处理事件的移除函数 return function(){ events[name].splice(index,1); } }, //关闭消息 off:function(name){ if(!events[name]) return; //消息存在,删除消息 delete events[name]; }, //消息发布 emit:function(name,msg){ //消息不存在,不处理 if(!events[name]) return; //消息存在,将该事件处理队列中每一个函数都执行一次 events[name].forEach(function(v,i){ v(msg); }); } } })(); var sayHello = scope.on('greeting',function(msg){ console.log('订阅消息:' + msg); }); var greeting = function(msg){ console.log('发布消息:' + msg); scope.emit('greeting', msg); } greeting('hello Panfen!')
Es gibt ein Ereignismodul in Nodejs, um den Beobachtermodus zu implementieren. Informationen zum Beobachtermodus finden Sie in Nodejs. Die meisten Module verfügen über ein integriertes Ereignismodul, sodass Sie Emit direkt starten können Ereignisse. und weiter, um auf Ereignisse zu warten, oder definieren Sie es zuerst wie folgt;
var EventEmitter = require('events').EventEmitter; var life = new EventEmitter(); life.setMaxListeners(11); //设置最大监听数,默认10 //发布和订阅sendName life.on('sendName',function(name){ console.log('say hello to '+name); }); life.emit('sendName','jeff'); //发布和订阅sendName2 function sayBeautiful(name){ console.log(name + ' is beautiful'); } life.on('sendName2',sayBeautiful); life.emit('sendName2','jeff');hasConfortListener: wird verwendet, um zu bestimmen, ob das ausgegebene Ereignis vorliegt ein Zuhörer
推送
Verwandte Artikel: 收听
Detaillierte Erklärung des klassischen JavaScript-Entwurfsmusters, des Strategiemusters
Das klassische JavaScript-Entwurfsmuster, das Einfache Beispiel für einen Factory-Mustercode
Detaillierte Erläuterung des klassischen JavaScript-Designmuster-Singleton-Musters
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in das Beobachtermuster von JavaScript-Entwurfsmustern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!