2011-12-13 5 views
3

Я пишу много небольших библиотек и модулей, и обычно эти библиотеки и модули имеют связанные с ними события. До сих пор я писал это, как (не укорачивается вниз много):Самый эффективный способ написать пользовательский .on() /. Bind() JavaScript

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

то пользователь будет делать что-то такое, как:

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

Есть лучше более производительный способ сделать это, хотя или это стандартный способ реализации этого? Я хочу простой API, чтобы я мог попасть в любой проект JS для поддержки этого поведения.

ответ

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 ('event')', вероятно, связано с тем, как люди используют 'unbind ('event')' в jQuery, где он удаляет все ссылки (если вы не добавите пространство имен, например 'event.foo') –

+0

@OscarGodson вам нужно удалить всех слушателей вручную. При вызове 'removeListener (ev)' удаляется последний прослушиватель по простому совпадению. (индекс равен -1, поэтому он удаляет последний элемент). Вы должны называть 'removeListener (ev, обработчик)'. – Raynos

0

Вы ищете Observer Pattern для JavaScript.

Spine и Backbone имеют некоторые хорошие реализации для наблюдателей.

Но новый красивый шаблон это шаблон Обещания, которые задокументированы в CommonJS

jQuery 1.7 реализовали и глубоко с помощью шаблона обещания.

Моя любимая реализация от Обещания модели является Q от @kriskowal

Я надеюсь, что это источники помогут вам в ваших поисках.

 Смежные вопросы

  • Нет связанных вопросов^_^