新聞中心
什么是事件發(fā)射器(Event Emitter)?
朋友們,作為一名軟件工程師,你一定用過(guò)Event Emitter,我們經(jīng)常用它來(lái)處理跨組件的通信場(chǎng)景。

網(wǎng)站制作、成都網(wǎng)站制作服務(wù)團(tuán)隊(duì)是一支充滿著熱情的團(tuán)隊(duì),執(zhí)著、敏銳、追求更好,是創(chuàng)新互聯(lián)的標(biāo)準(zhǔn)與要求,同時(shí)竭誠(chéng)為客戶提供服務(wù)是我們的理念。成都創(chuàng)新互聯(lián)把每個(gè)網(wǎng)站當(dāng)做一個(gè)產(chǎn)品來(lái)開(kāi)發(fā),精雕細(xì)琢,追求一名工匠心中的細(xì)致,我們更用心!
它觸發(fā)了一個(gè)每個(gè)人都可以收聽(tīng)的事件,并且可以在事件觸發(fā)時(shí)發(fā)送數(shù)據(jù)。
不同的庫(kù)提供不同的實(shí)現(xiàn),用于不同的目的,但基本思想是提供一個(gè)用于發(fā)布和訂閱事件的框架。
你想知道它背后的魔力嗎?本文將與你分享一個(gè)非常簡(jiǎn)單的解決方案來(lái)實(shí)現(xiàn)它。
我們一起來(lái)試試。
請(qǐng)用以下這個(gè)例子來(lái)玩一會(huì)兒。
Document
The data you sent me is:
輸出:
當(dāng)你點(diǎn)擊 Please send me data 按鈕時(shí),你會(huì)看到 count 的值越來(lái)越大,但是在你點(diǎn)擊 Cut off contact 之后,它就不再變化了。
這個(gè)例子很簡(jiǎn)單,但足以說(shuō)明有關(guān) Event Emitter 的一切。
來(lái),我們開(kāi)始吧!
Event Emitter 只需幾行代碼就可以完成,這真是太神奇了。
class EventEmitter {
on = (eventName, callback) => window.addEventListener(eventName, callback, false)
off = (eventName, callback) => window.removeEventListener(eventName, callback, false)
emit = (eventName, data) => window.dispatchEvent(new CustomEvent(eventName, { detail: data }))
}1. 監(jiān)聽(tīng)事件
const emitter = new EventEmitter()
const eventCallback = (event) => {
console.log('eventCallback', event.detail)
}
emitter.on('event-xxx', eventCallback)
2. 發(fā)布事件
eventCallback 將打印兩次數(shù)據(jù),因?yàn)槲覀儍纱伟l(fā)布了 event-xxx 事件。
emitter.emit('event-xxx', { name: 'fatfish' })
emitter.emit('event-xxx', { name: 'medium' })3.解除事件
當(dāng)我們解除 event-xxx 事件時(shí),不再打印 medium 和 fatfish。
emitter.off('event-xxx', eventCallback)
emitter.emit('event-xxx', { name: 'medium and fatfish' })CustomEvent 是謎題的答案
實(shí)現(xiàn) EventEmitter 的關(guān)鍵是 CustomEvent 和瀏覽器的事件機(jī)制,你可以從這里得到:https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent。
CustomEvent() 構(gòu)造函數(shù)創(chuàng)建一個(gè)新的 CustomEvent 對(duì)象?!獊?lái)自 MDN
// create custom events
const catFound = new CustomEvent('animalfound', {
detail: {
name: 'cat'
}
})
const dogFound = new CustomEvent('animalfound', {
detail: {
name: 'dog'
}
})
// add an appropriate event listener
window.addEventListener('animalfound', (e) => console.log(e.detail.name))
// dispatch the events
window.dispatchEvent(catFound)
window.dispatchEvent(dogFound)
實(shí)現(xiàn)事件發(fā)射器的另一種方法
雖然,這種方法很簡(jiǎn)單,但它依賴于瀏覽器環(huán)境,還有其他更好的解決方案嗎?
class EventEmitter {
constructor () {
this.events = {}
}
on (evt, callback, ctx) {
if (!this.events[ evt ]) {
this.events[ evt ] = []
}
this.events[ evt ].push(callback)
return this
}
emit (evt, ...payload) {
const callbacks = this.events[ evt ]
if (callbacks) {
callbacks.forEach((cb) => cb.apply(this, payload))
}
return this
}
off (evt, callback) {
// Cancel all subscribed events
if (typeof evt === 'undefined') {
delete this.events
} else if (typeof evt === 'string') {
// Delete the subscriber of the specified event
if (typeof callback === 'function') {
this.events[ evt ] = this.events[ evt ].filter((cb) => cb !== callback)
} else {
// Delete event directly
delete this.events[ evt ]
}
}
return this
}
}
const e1 = new EventEmitter()
const e1Callback = (name) => {
console.log(name, 'e1Callback')
}
const e2Callback = (name, sex) => {
console.log(name, 'e2Callback')
}
e1.on('evt1', e1Callback)
e1.on('evt2', e2Callback)
e1.emit('evt1', 'fatfish') // fatfish e1Callback
e1.emit('evt2', 'medium') // medium e2Callback
e1.off('evt1', e1Callback)
e1.emit('evt1', 'fatfish') // fatfish e1Callback will not be printed
e1.emit('evt2', 'medium') // medium e2Callback
寫(xiě)在最后
以上就是我今天跟你分享的關(guān)于事件發(fā)射器的全部?jī)?nèi)容,不知道你還有沒(méi)有其他更好的實(shí)現(xiàn)方法?如果有的話,請(qǐng)記得在留言區(qū)跟我分享你的解決方案,在此,非常感謝。
看完今天內(nèi)容,如果你覺(jué)得有用的話,請(qǐng)記得點(diǎn)贊我,關(guān)注我,并將這篇內(nèi)容分享給你的朋友們,也許能夠幫助到他。
最后,感謝你的閱讀,編程愉快!
當(dāng)前標(biāo)題:JavaScript中事件發(fā)射器(EventEmitters)背后的魔力
網(wǎng)址分享:http://www.dlmjj.cn/article/cccdccc.html


咨詢
建站咨詢
