安利一個(gè) 事件代理庫(kù)
var fs = require('fs')
var eventProxy = require('eventProxy')
var ep = new eventProxy()
ep.on('got',function(content){
console.log(content)
})
fs.readFile('tmp','utf-8', function(err, content){
ep.emit('got', content)
})
最基本的方法就是on和emit,負(fù)責(zé)綁定事件監(jiān)聽器和發(fā)出事件疾捍,在上面的代碼中奈辰,當(dāng)fs完成文件的讀操作之后,就發(fā)出got事件乱豆,這個(gè)時(shí)候之前的事件監(jiān)聽器就會(huì)捕獲到它并執(zhí)行回調(diào)函數(shù)奖恰。
Do it yourself
var EventProxy = function () {
this._callbacks = {};
};
EventProxy.prototype.on = function(ev, callback){
this._callbacks[ev] = callback;
return this;
}
EventProxy.prototype.emit = function(eventname){
var callback = this._callbacks[eventname]
if(!callback){
return console.log("no this event listener")
}
var args = [];
for (var j = 1; j < arguments.length; j++) {
args.push(arguments[j]);
}
callback.apply(this, args)
return this;
}
我們只需要給event加上一個(gè)_callbacks數(shù)組,每次注冊(cè)監(jiān)聽器的時(shí)候宛裕,把callback放進(jìn)去就好啦瑟啃,而當(dāng)emit事件的時(shí)候,其實(shí)就是去這個(gè)_callbacks數(shù)組中找到對(duì)應(yīng)的回調(diào)函數(shù)并執(zhí)行揩尸。
var ep = new EventProxy()
ep.on('got', function(content){
console.log(content)
})
fs.readFile('tmp', 'utf-8', function(err,content){
ep.emit('got', content)
})
remove
有時(shí)候我們需要?jiǎng)h除注冊(cè)的監(jiān)聽器
EventProxy.prototype.remove = function(eventname){
if(!this._callbacks[eventname]){
return console.log("no such event listener")
}
delete this._callbacks[eventname]
}
once
有時(shí)候我們希望我們注冊(cè)的事件只執(zhí)行一次蛹屿,也就是說(shuō)事件一旦被觸發(fā),就立刻刪除岩榆。
EventProxy.prototype.once = function(eventname,callback){
var that = this;
var wrapper = function(){
callback.apply(that, arguments)
that.remove(eventname);
}
this.on(eventname, wrapper)
return this
}
上面的代碼看起來(lái)稍微有點(diǎn)復(fù)雜错负,其實(shí)很簡(jiǎn)單。原來(lái)我們?cè)谧?cè)事件的時(shí)候勇边,是直接把回調(diào)函數(shù)注冊(cè)到其中犹撒。而現(xiàn)在,我們把回調(diào)函數(shù)“裝飾”起來(lái)粒褒,使其在回調(diào)執(zhí)行后识颊,移除事件監(jiān)聽器。下面我們來(lái)測(cè)試一下
var ep = new EventProxy()
ep.once('got', function(content){
console.log(content)
})
fs.readFile('tmp', 'utf-8', function(err,content){
ep.emit('got', content)
})
fs.readFile('tmp', 'utf-8', function(err,content){
ep.emit('got', content)
})
我們兩次讀取文件怀浆,但是文件只被打印出來(lái)一次。原因是當(dāng)我們第一次調(diào)用完回調(diào)后,got事件的監(jiān)聽器就被移除了砌滞。酷函筋!