一、发布订阅者模式js
发布订阅者模式又称为观察者模式,是一种常见的软件设计模式,属于行为型模式。该模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知并被自动更新。
在JavaScript中,我们可以使用事件机制来实现发布订阅者模式。事件机制本质上就是一种发布订阅者模式的实现。我们可以通过事件机制来为一个事件注册回调函数,当这个事件触发时,所有注册的回调函数都会被依次调用。
class EventEmitter {
constructor() {
this._events = {}
}
on(event, callback) {
if (!this._events[event]) {
this._events[event] = []
}
this._events[event].push(callback)
}
emit(event, ...args) {
if (!this._events[event]) {
return
}
this._events[event].forEach(fn => {
fn.apply(this, args)
})
}
}
二、发布订阅者模式和观察者模式代码
发布订阅者模式和观察者模式在概念上很相似,都是建立了一种一对多的依赖关系。但是它们的实现方式有所不同。在观察者模式中,观察者对象需要直接订阅主题对象,而在发布订阅者模式中,发布者和订阅者之间则没有直接的联系,而是通过发布-订阅通道来进行通信。
下面是观察者模式和发布订阅者模式的示例代码:
//观察者模式
class Subject {
constructor() {
this.observers = []
}
addObserver(observer) {
this.observers.push(observer)
}
removeObserver(observer) {
const index = this.observers.indexOf(observer)
if (index !== -1) {
this.observers.splice(index, 1)
}
}
notify() {
this.observers.forEach(observer => observer.update())
}
}
class Observer {
constructor(name, subject) {
this.name = name
this.subject = subject
this.subject.addObserver(this)
}
update() {
console.log(`${this.name} has been notified`)
}
}
const subject = new Subject()
const observer1 = new Observer('observer1', subject)
const observer2 = new Observer('observer2', subject)
subject.notify() // 'observer1 has been notified', 'observer2 has been notified'
//发布订阅者模式
class EventBus {
constructor() {
this.subscribers = {}
}
subscribe(event, callback) {
if (!this.subscribers[event]) {
this.subscribers[event] = []
}
this.subscribers[event].push(callback)
}
unsubscribe(event, callback) {
if (!this.subscribers[event]) {
return
}
const index = this.subscribers[event].indexOf(callback)
if (index !== -1) {
this.subscribers[event].splice(index, 1)
}
}
publish(event, ...args) {
if (!this.subscribers[event]) {
return
}
this.subscribers[event].forEach(fn => {
fn.apply(this, args)
})
}
}
const eventBus = new EventBus()
const callback1 = () => console.log('callback1 is called')
const callback2 = () => console.log('callback2 is called')
eventBus.subscribe('test', callback1)
eventBus.subscribe('test', callback2)
eventBus.publish('test') // callback1 is called', 'callback2 is called'
eventBus.unsubscribe('test', callback1)
eventBus.publish('test') // 'callback2 is called'
三、发布订阅者模式实例代码
下面是一个发布订阅者模式的实例,我们模拟了一个购买商品的场景。当用户购买商品时,我们将触发一个名为“buy”事件,并传递商品名称和价格。购物车和订单模块可以订阅该事件,以便在用户购买商品时更新购物车和订单信息。
class EventBus {
constructor() {
this.subscribers = {}
}
subscribe(event, callback) {
if (!this.subscribers[event]) {
this.subscribers[event] = []
}
this.subscribers[event].push(callback)
}
unsubscribe(event, callback) {
if (!this.subscribers[event]) {
return
}
const index = this.subscribers[event].indexOf(callback)
if (index !== -1) {
this.subscribers[event].splice(index, 1)
}
}
publish(event, ...args) {
if (!this.subscribers[event]) {
return
}
this.subscribers[event].forEach(fn => {
fn.apply(this, args)
})
}
}
const eventBus = new EventBus()
class Cart {
constructor() {
this.items = []
eventBus.subscribe('buy', this.add.bind(this))
}
add(item) {
this.items.push(item)
console.log(`Item ${item.name} is added to the cart`)
}
}
class Order {
constructor() {
this.items = []
eventBus.subscribe('buy', this.add.bind(this))
}
add(item) {
this.items.push(item)
console.log(`Item ${item.name} is added to the order`)
}
}
const cart = new Cart()
const order = new Order()
eventBus.publish('buy', { name: 'iPhone', price: '999' })
// 'Item iPhone is added to the cart', 'Item iPhone is added to the order'
四、发布订阅者模式怎么理解
发布订阅者模式是一种解耦的方式,将生产者和消费者完全解耦,使得它们之间没有直接的依赖关系。生产者和消费者之间仅仅通过一个中间件来通信。生产者将消息发布到中间件中,而消费者则从中间件中订阅消息。这种解耦方式使得系统变得更加松散,更容易扩展和维护。
发布者订阅者模式可以应用于很多地方,比如事件机制、消息队列、Redux等。在Vue.js中,也使用了类似的机制来实现组件间的通信,将组件间的通信从父子关系中解耦出来,使得组件之间具有更高的可扩展性和复用性。
五、发布订阅者模式面试题
以下是一些与发布订阅者模式相关的面试题:
1、请说出发布订阅者模式和观察者模式的区别。
答:在发布订阅者模式中,发布者和订阅者之间没有直接的联系,而是通过一个中间件来进行通信。而在观察者模式中,观察者对象需要直接订阅主题对象。
2、请说出事件机制的实现方式。
答:事件机制本质上就是一种发布订阅者模式的实现。我们可以为一个事件注册回调函数,当这个事件触发时,所有注册的回调函数都会被依次调用。
六、发布订阅者模式的实现
下面是一个基于ES6的发布订阅者模式的实现:
class EventBus {
constructor() {
this.subscribers = new Map()
}
subscribe(event, callback) {
if (!this.subscribers.has(event)) {
this.subscribers.set(event, [])
}
this.subscribers.get(event).push(callback)
}
unsubscribe(event, callback) {
if (!this.subscribers.has(event)) {
return
}
const index = this.subscribers.get(event).indexOf(callback)
if (index !== -1) {
this.subscribers.get(event).splice(index, 1)
}
}
publish(event, ...args) {
if (!this.subscribers.has(event)) {
return
}
this.subscribers.get(event).forEach(fn => {
fn.apply(this, args)
})
}
}
const eventBus = new EventBus()
eventBus.subscribe('test', () => console.log('test is called'))
eventBus.publish('test') // 'test is called'
eventBus.unsubscribe('test') // remove all subscribers for 'test' event
七、发布订阅者模式在Vue中的应用
在Vue.js中,组件间的通信可以通过props传递数据、事件派发和监听等方式来实现。其中事件派发和监听的机制就是基于发布订阅者模式来实现的。当组件A需要向组件B发送事件时,它会使用$emit方法来触发一个名为event的事件,并传递参数值。而组件B则需要使用$on方法来注册这个事件,并在回调函数中处理参数值。
以下是一个在Vue中使用发布订阅者模式来进行组件通信的实例:
//Parent.vue
<template>
<Child @eventName="handleEvent"></Child>
</template>
<script>
import { EventBus } from '@/event-bus.js'
export default {
methods: {
handleEvent() {
// handle event here
}
},
mounted() {
EventBus.$on('eventName', this.handleEvent)
},
beforeDestroy() {
EventBus.$off('eventName', this.handleEvent)
}
}
</script>
//Child.vue
<template>
<button @click="sendEvent">Send Event</button>
</template>
<script>
import { EventBus } from '@/event-bus.js'
export default {
methods: {
sendEvent() {
EventBus.$emit('eventName', data)
}
}
}
</script>
//event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/235925.html
微信扫一扫
支付宝扫一扫