nodejs 의 EventEmitter 실현
Node. js 의 많은 대상 이 이 벤트 를 나 눠 줍 니 다. 하나의 net. server 대상 은 새로운 연결 이 있 을 때마다 이 벤트 를 촉발 합 니 다. fs. readStream 대상 은 파일 이 열 릴 때 이 벤트 를 촉발 합 니 다.이 모든 사건 의 대상 은 events. EventEmitter 의 인 스 턴 스 입 니 다.
아래 의 간단 한 실현:
function EventEmitter() {
this.events = {}
this.counts = 0
this.maxNum = 10
// :newListener -> 。removeListener -> 。
this.innerEvent = {
NEWLISTENER: 'newListener',
REMOVELISTENER: 'removeListener'
}
}
// 。
function addListener(eventName, callback) {
if (typeof callback !== 'function') return
if (!this.events[eventName]) {
if (!this._isInnerEvent(eventName)) {
this.events[eventName] = [{ type: 'on', callback }]
this.counts++
if (this.counts > this.maxNum) {
console.warn(` :${this.counts} , ${this.maxNum} `)
}
if (this.events[this.innerEvent.NEWLISTENER]) {
this.emit(this.innerEvent.NEWLISTENER, eventName)
}
} else {
this.events[eventName] = { type: 'on', callback }
}
} else {
this.events[eventName].push({ type: 'on', callback })
}
}
EventEmitter.prototype = {
_toString: function (obj) {
return Object.prototype.toString.call(obj).slice(8, -1)
},
_isInnerEvent: function (eventName) {
return !!this.innerEvent[eventName.toUpperCase()]
},
addListener: addListener,
on: addListener,
// , true, false。
emit: function () {
let arg = Array.prototype.slice.call(arguments)
let eventName = arg[0]
let params = arg.slice(1)
if (!this._isInnerEvent(eventName)) {
if (this._toString(this.events[eventName]) === 'Array' && this.events[eventName].length) {
this.events[eventName].forEach(event => {
let { type, callback } = event
callback.apply(null, params)
if (type === 'once') {
this.events[evtName].splice(index, 1)
}
})
return true
}
return false
} else {
this.events[eventName].callback.apply(null, params)
if (this.events[eventName].type === 'once') {
delete this.events[eventName]
}
}
},
// , , 。
once: function (eventName, callback) {
if (typeof callback !== 'function') return
if (!this.events[eventName]) {
if (!this._isInnerEvent(eventName)) {
this.events[eventName] = [{ type: 'once', callback }]
this.counts++
if (this.counts > this.maxNum) {
console.warn(` :${this.counts} , ${this.maxNum} `)
}
if (this.events[this.innerEvent.NEWLISTENER]) {
this.emit(this.innerEvent.NEWLISTENER, eventName)
}
} else {
this.events[eventName] = { type: 'once', callback }
}
} else {
this.events[eventName].push({ type: 'once', callback })
}
},
// , 。
removeListener: function (eventName, callback) {
if (this._toString(this.events[eventName]) === 'Array') {
let _events = this.events[eventName].concat()
for (let i = 0; i < _events.length; i++) {
if (_events[i].callback === callback) {
this.events[eventName].splice(i, 1)
return
}
}
}
},
// , , 。
removeAllListeners: function (eventName) {
if (eventName) {
if (this.events[eventName]) {
delete this.events[eventName]
if (!this._isInnerEvent(eventName)) {
this.counts--
if (this.events[this.innerEvent.REMOVELISTENER]) {
this.emit(this.innerEvent.REMOVELISTENER, eventName)
}
}
}
} else {
this.events = {}
this.counts = 0
}
},
// , EventEmitters 10 。 setMaxListeners 。
setMaxListeners: function (num) {
this.maxNum = num
},
// 。
listeners: function (eventName) {
if (this._toString(this.events[eventName]) === 'Array') {
let _events = this.events[eventName].concat()
let newArray = []
_events.forEach(item => {
newArray.push(item.callback)
})
return newArray
}
},
//
listenerCount: function (eventName) {
if (this._toString(this.events[eventName]) === 'Array') {
return this.events[eventName].length
}
}
}
var eventEmit = new EventEmitter()
eventEmit.on('newListener', function newListener(eventName) {
console.log('>>>>newListener ---', eventName)
})
eventEmit.on('removeListener', function removeListener(eventName) {
console.log('>>>>removeListener ---', eventName)
})
console.log(eventEmit)
function event1() {
console.log('event1')
}
eventEmit.on('event', event1)
eventEmit.on('event1', event1)
eventEmit.on('event', function event2() {
console.log('event2')
})
eventEmit.emit('event')
eventEmit.emit('event1')
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.