0

我希望能够将公共方法用于回调,而不是将其作为参数传递

如在

 function Car() {

    var that = this;

    this.onGearChanged = function(callback) {

       callback();
    }; 

   setTimeout(that.onGearChanged, 2000);
}

var car = new Car();
car.onGearChanged(function(){
   console.log("gear changed");

});

代替

var onGearChanged = function(){
    console.log("gear changed")
}
var car = new Car(arg, arg, onGearChange);

我该怎么办?我应该遵循观察者模式吗?

4

2 回答 2

1

代码或多或少会复杂,这取决于您不清楚的要求。如果不需要,请不要使用模式,并且可以根据您的要求以多种方式调整模式。如果您真的不需要它,请不要尝试构建万能解决方案。

如果你有很多观察者并且在汽车创建时就知道他们,你可以使用

 function Car(onGearChangedArray) {
    this.triggerGearChanged = function() {
       for (var i=0;i<onGearChangedArray.length;i++) {
         onGearChangedArray[i]();
       }
    }; 
    window.setTimeout(this.triggerGearChanged,2000);
 }

 var car = new Car([function(){
   console.log("gear changed");
 }]);

如果你只有一个观察者,你可以摆脱 for 循环。

但是,如果您需要在运行时灵活地添加它们:

 function Car() {
    var onGearChangedCallbacks = [];
    this.onGearChanged = function(callback) {
       onGearChangedCallbacks.push(callback);
    };
    this.triggerGearChanged = function() {
       for (var i=0;i<onGearChangedCallbacks.length;i++) {
         onGearChangedCallbacks[i]();
       }
    }; 
    window.setTimeout(this.triggerGearChanged,2000);
 }

 var car = new Car();
 car.onGearChanged(function(){
   console.log("gear changed");
 });

或者,如果您想将其抽象到下一个级别

 function Event() {
    var callbacks = [];
    this.bind = function(callback) {
       callbacks.push(callback);
    };
    this.fire = function() {
       for (var i=0;i<callbacks.length;i++) {
         callbacks[i]();
       }
    }; 
 }

 function Car() {
    this.gearChanged = new Event();
    window.setTimeout(this.gearChanged.fire,2000);
 }

 var car = new Car();
 car.gearChanged.bind(function(){
   console.log("gear changed");
 });

感谢 Khanh TO 的抽象想法,我只是想在没有参数的情况下展示它。

您还可以考虑使用更复杂的东西,这样您就不需要自己编写此事件处理代码(如错误处理等),但同样,这取决于您的需要。您需要快速失败的策略,还是应该只记录错误?听众必须注销吗?您能否将自己困在一个无限循环中,因为 triggerGearChanged 可能会导致另一个 triggerGearChanged?是否需要传递参数?记住要尽可能简单,所以如果你不需要传递参数,那就不要这样做。

如果你喜欢 unserscore.js,一个好的开始可能是http://mattmueller.me/blog/underscore-extension-observer-pattern

于 2013-07-31T14:29:25.003 回答
1

我认为你需要这样的东西:

function Event(sender) {
    this._sender = sender;
    this._listeners = [];
}

Event.prototype = {
    attach: function (listener) {
        this._listeners.push(listener);
    },
    notify: function (args) {
        for (var i = 0; i < this._listeners.length; i++) {
            this._listeners[i](this._sender, args);
        }
    }
};

Car上课:

function Car(gear) {
     var self = this;

     self.Gear = gear;
     self.GearChanged = new Event(this);

     //Example method to trigger your GearChanged event. In your real code, you may have different logic
     self.changeGear = function (newGear){
         self.Gear = newGear;
         //notify all subscribers
         self.GearChanged.notify(newGear);
     }
}

订阅事件的示例代码:

var car = new Car("gear");
car.GearChanged.attach(function (sender,args){
    console.log("gear changed");
    console.log("new gear value is:" + args);
});
//do some logic that may trigger gearChanged event.
car.changeGear("new Gear");

您可以附加更多事件处理程序,所有这些事件处理程序都将被调用。您还可以使用此结构轻松添加更多事件,例如:tireChanged,..。

于 2013-07-31T14:32:43.030 回答