2011-12-13 3 views
3

私は小さなライブラリとモジュールをたくさん書いていますが、通常これらのライブラリとモジュールにはいくつかのイベントが関連付けられています。今まで私は(多くのダウン短縮)のようにこれらを書いてきた:カスタムの.on()/。bind()を書く最もパフォーマンスのよい方法JavaScript

Library.prototype.on = function(event, callback){ 
    self = this; 
    self.events[event] = callback; 
} 

その後、ユーザーはのような何かをするだろう:

Library.on('foo',function(){ 
    console.log('bar'); 
}); 

このかかわらを行うには良い、よりパフォーマンスの高い方法はありますこれを実装する標準的な方法ですか?私はこの動作をサポートするためにJSプロジェクトにドロップできるシンプルなAPIが必要です。

答えて

2
var EventEmitter = { 
    constructor: function _constructor() { 
     this._events = []; 
     return this; 
    }, 
    on: function _on(ev, handler) { 
     if (!this._events[ev]) { 
      this._events[ev] = []; 
     } 
     this._events[ev].push(handler); 
    }, 
    removeListener: function _removeListener(ev, handler) { 
     if (!this._events[ev]) return; 
     this._events[ev].splice(this._events[ev].indexOf(handler), 1); 
    }, 
    removeAll: function _removeAll(ev) { 
     delete this._events[ev]; 
    }, 
    emit: function _emit(ev, data) { 
     if (!this._events[ev]) return; 
     this._events[ev].forEach(invokeHandler); 

     function invokeHandler(handler) { 
      handler(data); 
     } 
    } 
}; 

私は迅速かつ汚いカスタムイベントを必要とするとき私が使用して小さなEventEmitterを持っています。

私の実装と実装の唯一の違いは、私がイベントごとに複数のコールバックを許可する点です。私はEventEmitter2

+0

おかげのようなイベントライブラリを使用して深刻なものについては

、これは完全に働いている:) –

+0

だけ奇妙なことは、のremoveListenerが唯一の最後に追加されたが削除されていることです。 'removeListener( 'event')'の意図された使用は、(event.foo'のような名前空間を追加しない限り)人々が 'unbind( 'event')'を使ってすべての参照を削除する方法でしょうか? –

+0

@OscarGodsonすべてのリスナーを手動で削除する必要があります。 'removeListener(ev) 'を呼び出すと、最後のリスナーが完全な偶然によって削除されます。 (インデックスは-1なので、最後のアイテムは削除されます)。あなたは 'removeListener(ev、handler)'を呼び出すべきです。 – Raynos

0

JavaScriptをお探しの場合はObserver Patternをご利用ください。

SpineおよびBackboneには、オブザーバのための素晴らしい実装がいくつかあります。

しかし、新しい素敵なパターンが実装されているCommonJS

jQuery 1.7で文書化されていると深く約束パターンを使用している約束のパターンです。約束のパターンから

私のお気に入りの実装では、私はこのソースがあなたの探求であなたを助けることを、願ってい@kriskowal

からQです。

関連する問題