欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

javascript 發布訂閱模式

錢旭東1年前8瀏覽0評論

Javascript是一門動態語言,實現高級特性的方式有很多。發布訂閱模式是其中之一,它是建立在事件相關技術的基礎上,用于更好地組織代碼邏輯和實現松散的耦合。當模塊間需要互相通信,但又不能緊耦合的時候,發布訂閱模式發揮出很好的作用。

發布訂閱模式的核心機制就是EventEmitter類。在Node.js和瀏覽器環境中事件相關的API也都是基于該類的實現。以下是一個簡單的示例:

class EventEmitter {
constructor() {
this.events = {}
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = []
}
this.events[eventName].push(callback)
}
emit(eventName, ...args) {
const callbacks = this.events[eventName]
if (callbacks) {
callbacks.forEach(cb =>cb(...args))
}
}
removeListener(eventName, callback) {
const callbacks = this.events[eventName]
if (callbacks) {
const index = callbacks.indexOf(callback)
if (index !== -1) {
callbacks.splice(index, 1)
}
}
}
}

在此基礎上,廣播(event.emit)和訂閱(event.on)行為就可以通過構造EventEmitter實例來實現了:

const event = new EventEmitter()
// 添加一個監聽器
event.on('say_hello', () =>{
console.log('Hello World!')
})
// 廣播事件
event.emit('say_hello') // 輸出 'Hello World!'

到了這個地步,可以加上異步廣播(event.emitAsync)和異步訂閱(event.onAsync)以及匿名監聽器支持,完善發布訂閱模式的機制:

class EventEmitter {
constructor() {
this.events = {}
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = []
}
this.events[eventName].push(callback)
}
onAsync(eventName, asyncCallback) {
this.on(eventName, function callbackWrapper(...args) {
Promise.resolve(asyncCallback(...args))
.catch(console.error)
})
}
emit(eventName, ...args) {
const callbacks = this.events[eventName]
if (callbacks) {
callbacks.forEach(cb =>cb(...args))
}
}
async emitAsync(eventName, ...args) {
const callbacks = this.events[eventName]
if (callbacks) {
await Promise.all(callbacks.map(cb =>cb(...args)))
}
}
removeListener(eventName, callback) {
const callbacks = this.events[eventName]
if (callbacks) {
const index = callbacks.indexOf(callback)
if (index !== -1) {
callbacks.splice(index, 1)
}
}
}
}

現在,你甚至可以像這樣來注冊操作事件:

const event = new EventEmitter()
// 添加異步監聽器
event.onAsync('async_event', async () =>{
await new Promise(resolve =>setTimeout(resolve, 2000))
console.log('async_event done!')
})
// 添加匿名監聽器
event.onAsync('anonymous_event', async () =>{
console.log('anonymous_event done!')
})

而事件的廣播和處理則仍舊像這樣:

// 廣播事件
event.emit('async_event').catch(console.error)
event.emitAsync('anonymous_event').catch(console.error)

這樣,發布訂閱模式的基本機制就被實現了。你可以繼續封裝EventEmitter,使其更加符合自己的特性,比如支持一次注冊多個事件處理器、支持指定監聽器的優先級、支持在異步廣播中安全的處理錯誤等等。

總之,發布訂閱模式是一個非常有用的技術,它是Javascript中實現復雜流程控制、解耦代碼邏輯的常用方式。