2012-04-11 5 views
1

Ich versuche, ein einfaches Pub/Sub-Objekt in Javascript zu implementieren, und hier ist mein Code:Javascript pub/sub Implementierung arbeitet für Funktionen, aber keine Objekte Methoden

var PubSub=new function(){ 
    this.subscriptions=[]; 
    this.subscribe=function(topic,callback){ 
     if(!this.subscriptions[topic]){ 
      this.subscriptions[topic]=[]; 
     } 
     this.subscriptions[topic].push(callback); 
    } 
    this.unsubscribe=function(topic,callback){ 
     if(this.subscriptions[topic]){ 
      for(var i=this.subscriptions[topic].length-1;i>=0;i--){ 
       if(this.subscriptions[topic][i]==callback){ 
        this.subscriptions[topic].splice(i,1); 
       } 
      } 
     } 
    } 
    this.publish=function(topic,data){ 
     if(this.subscriptions[topic]){ 
      for(var i=this.subscriptions[topic].length-1;i>=0;i--){ 
       this.subscriptions[topic][i](data); 
      } 
     } 
    } 
} 

nun eine einfache Funktion der abonnieren und dann ein paar Sachen zu veröffentlichen funktioniert super:

PubSub.subscribe("test",print); //print: shell function 
PubSub.publish("test","hello"); //print outputs "hello" 

Aber eine Funktion zeichnen, die Methode ist ein Objekt doen 'T Arbeit ist:

var a=new function(){ 
    this.c=0; 
    this.i=function(x){ 
     this.c+=x; 
    } 
} 
PubSub.subscribe("test",a.i); 
PubSub.publish("test",17); 
a.c; //is still 0 

Ich habe auch versucht, gelten mit (unter der Annahme Daten ist ein Array):

PubSub.publish=function(topic,data){ 
    ... 
     this.subscriptions[topic][i].apply(this,data); 
    ... 
} 

Es funktioniert auch nicht, obwohl ich es nicht das gleiche Problem glauben: Ich denke, das this gebene Objekt durch das Objekt this Überschreibungen gelten von a und daher a.i versucht PubSub.a statt a.a ...

+0

Es sollte auch beachtet werden, dass: thissubscriptions = []; sollte stattdessen this.subscriptions = {} sein; basierend darauf, wie Sie es verwenden. – cweston

Antwort

2

Wenn Sie a.i-PubSub.subscribe passieren zu setzen, Sie „losgelöst“ die i Funktion von a, dessen Aufrufkontext haben. Verwenden entweder eine anonyme Funktion, die Bindung zu erhalten:

PubSub.subscribe("test", function (x) { a.i(x); }); 

oder Function.bind zu erhalten verwenden a als this, wenn i genannt:

PubSub.subscribe("test", a.i.bind(a)); 

N.B. Function.bind wird nicht in allen Browsern unterstützt, daher sollten Sie use the shim.

+1

Ok danke, ich verstehe warum mein Beispiel nicht funktioniert hat! Wenn ich die anonyme Funktion verwende, funktioniert 'abmelden' nicht mehr, sondern deklariert die Funktion zuerst, so dass sie einen Namen hat, und dann an 'subscribe' weiterleiten löst dieses Problem ... – Alex