观察者和订阅-发布模式
观察者模式
class Observe {
constructor() {
this.events = []
}
subscribe(func){
if(this.events.includes((func)))return
this.events.push(func)
}
unsubscribe(func){
const index = this.events.findIndex(func)
if(index!==-1){
this.events.splice(index, 1)
}
}
notify(...args){
this.events.forEach(func=>{
func.apply(args)
})
}
}
// test case
const observe = new Observe()
observe.subscribe((...args)=>{
console.log(`this is first subject `,args)
})
observe.subscribe((...args)=>{
console.log(`this is second subject `,args)
})
observe.notify('memeda')
result
this is first subject Array(0)
this is second subject Array(0)
订阅-发布模式
type EventHandler = (payload:any) => void
class EventEmitter {
private events = new Map<string,EventHandler[]>()
subscribe(topic:string,...handlers:EventHandler[]):EventHandler[]{
let topics = this.events.get(topic)
if(topics){
topics.push(...handlers)
}else{
topics = [...handlers]
this.events.set(topic, topics)
}
return topics
}
unsubscribe (topic:string, handler?:EventHandler):boolean {
let IS_OK = false
const topics = this.events.get(topic)
if(topics){
if(handler){
const index = topics.findIndex(func=>func===handler)
if(index!==-1){
topics.splice(index,1)
IS_OK = true
}else{
IS_OK = false
}
}else{
this.events.delete(topic)
}
}else{
IS_OK = false
}
return IS_OK
}
notify(topic:string,...args:any[]){
const topics = this.events.get(topic)
if(topics){
topics.forEach(handler=>{
handler(args)
})
}
}
}
const eventEmitter:EventEmitter = new EventEmitter()
const handler = payload => {
console.log('blog updated, content is :', payload)
}
eventEmitter.subscribe('update:blog',handler)
eventEmitter.notify('update:blog', 'this is sync task')
setTimeout(()=>{
eventEmitter.notify('update:blog','macrotask update')
},0)
Promise.resolve().then(()=>{
eventEmitter.notify('update:blog','microtask update')
})
requestAnimationFrame(()=>{
eventEmitter.notify('update:blog','requestAnimationFrame update')
})
setTimeout(()=>{
const isOk = eventEmitter.unsubscribe('update:blog',handler)
console.log('times up, unsubscribe result is :',isOk)
eventEmitter.notify('update:blog','macrotask update in 10 second')
},3*1000)
result
blog updated, content is : ["this is sync task"] app.ts:51
blog updated, content is : ["microtask update"] app.ts:51
blog updated, content is : ["requestAnimationFrame update"] app.ts:51
blog updated, content is : ["macrotask update"] app.ts:73
times up, unsubscribe result is : true
Last updated
Was this helpful?