Emitter 对象事件库
接口
- on/addEventListener
- once
- off/removeListener/removeAllListeners/removeEventListener
- emit
- listeners
- hasListeners
继承方式
function Job(){
EventEmitter.call(this);
// custom initialization here
}
Job.prototype = new EventEmitter;
- 该库使用的方式(可以依照具体情况选择方式进行添加)
//As an Emitter instance:
var Emitter = require('emitter');
var emitter = new Emitter;
emitter.emit('something');
//As a mixin:
var Emitter = require('emitter');
var user = { name: 'tobi' };
Emitter(user);
user.emit('im a user');
//As a prototype mixin:
var Emitter = require('emitter');
Emitter(User.prototype);
- 实现: 通过mixin混合函数将事件函数绑定到对象上
function mixin(obj) {
for (var key in Emitter.prototype) {
obj[key] = Emitter.prototype[key];
}
return obj;
- 接口实现细节
- once一次调用:回调函数进行封装,调用该函数前调用off进行移除事件
Emitter.prototype.once = function(event, fn){
var self = this;
this._callbacks = this._callbacks || {};
function on() {
self.off(event, on);
fn.apply(this, arguments); //防止回调函数的this变成window
}
on.fn = fn; //这个是为了移除使用,不需要给on保留能索引到的变量,在remove的时候,判断cb.fn是不是跟移除的函数是一致的
this.on(event, on);
return this;
};
Emitter.prototype.removeEventListener = function(event, fn){
this._callbacks = this._callbacks || {};
// all
if (0 == arguments.length) {
this._callbacks = {};
return this;
}
// specific event
var callbacks = this._callbacks[event];
if (!callbacks) return this;
// remove all handlers
if (1 == arguments.length) {
delete this._callbacks[event];
return this;
}
// remove specific handler
var cb;
for (var i = 0; i < callbacks.length; i++) {
cb = callbacks[i];
if (cb === fn || cb.fn === fn) { //cb.fn === fn是用于once一次调用保留的回调函数
callbacks.splice(i, 1);
break;
}
}
return this;
};
* 代码不如seajs的好理解
seajs.off = function (name, callback) {
// Remove *all* events
if (!(name || callback)) {
events = data.events = {}
return seajs
}
var list = events[name]
if (list) {
if (callback) {
for (var i = list.length - 1; i >= 0; i--) {
if (list[i] === callback) {
list.splice(i, 1)
}
}
}
else {
delete events[name]
}
}
return seajs
}
Emitter.prototype.emit = function(event){
this._callbacks = this._callbacks || {};
var args = [].slice.call(arguments, 1)
, callbacks = this._callbacks[event];
if (callbacks) {
callbacks = callbacks.slice(0);
for (var i = 0, len = callbacks.length; i < len; ++i) {
callbacks[i].apply(this, args);
}
}
return this;
};
* 似乎没有必要添加callbacks = callbacks.slice(); 处理函数并不会改变callbacks数组,但有一种实现就需要这样子做:
while ((fn = list.shift())) {
fn.apply(this, args);
}