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

オブザーバーが 1 つしかない場合は、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 に答える