【问题标题】:Javascript pub/sub implementation works for functions, but not objects' methodsJavascript pub/sub 实现适用于函数,但不适用于对象的方法
【发布时间】:2012-04-23 20:10:42
【问题描述】:

我正在尝试在 javascript 中实现一个简单的 Pub/Sub 对象,这是我的代码:

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);
            }
        }
    }
}

现在,订阅一个简单的函数,然后发布一些东西效果很好:

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

但是,订阅一个作为对象方法的函数是行不通的:

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

我也尝试过使用 apply(假设 data 是一个数组):

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

它也不起作用,尽管我相信这不是同一个问题:我认为 apply 传递的 this 对象覆盖了 athis 对象,因此 a.i 尝试设置 @987654329 @ 而不是 a.a...

【问题讨论】:

  • 还需要注意的是:this.subscriptions=[];应该改为 this.subscriptions={};根据您的使用方式。

标签: javascript function object methods publish-subscribe


【解决方案1】:

当您将a.i 传递给PubSub.subscribe 时,您已将i 函数从a(其调用上下文)中“分离”出来。要么使用匿名函数来维护绑定:

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

或在调用i 时使用Function.binda 保留为this

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

注意并非所有浏览器都支持Function.bind,因此您需要use the shim

【讨论】:

  • 好的,谢谢,我明白为什么我的示例不起作用了!当我使用匿名函数时,unsubscribe 不再起作用,但先声明该函数,使其具有名称,然后将其传递给subscribe 即可解决该问题...
猜你喜欢
  • 2012-11-24
  • 2013-05-24
  • 2017-11-22
  • 2022-11-09
  • 2023-03-29
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多