做网站能接到项目工程吗,深圳vi设计手册,女生学软件工程后悔了,网站推广的基本手段目录 一、常见实现方案1.1 使用事件发射器#xff08;Event Emitter#xff09;1.2 自定义事件系统#xff08;EventBus#xff09;1.3 使用库如 PubSubJS1.4 使用框架内置的状态管理工具Vue.jsReact (使用 Context API 或 Redux) 二、先后关系2.1 缓存事件数据2.2 使用 Re… 目录 一、常见实现方案1.1 使用事件发射器Event Emitter1.2 自定义事件系统EventBus1.3 使用库如 PubSubJS1.4 使用框架内置的状态管理工具Vue.jsReact (使用 Context API 或 Redux) 二、先后关系2.1 缓存事件数据2.2 使用 Redux 或 Vuex 等状态管理工具2.3 使用本地存储或 IndexedDB 在前端开发中发布订阅是一种常见的开发场景允许一个对象发布者发布事件而多个对象订阅者可以订阅并接收这些事件。
发布订阅在设计模式中可以理解为 观察者模式 / Observer Pattern
一、常见实现方案
以下是一些常见的实现方案
1.1 使用事件发射器Event Emitter
许多 JavaScript 框架和库内置了事件发射器机制例如 Node.js 的 EventEmitter 类。
const EventEmitter require(events);
const eventEmitter new EventEmitter();// 定义事件
eventEmitter.on(event, (data) {console.log(Event received:, data);
});// 触发事件
eventEmitter.emit(event, Hello World!);1.2 自定义事件系统EventBus
自己实现一个简单的发布订阅系统可以通过维护一个事件监听器的映射表来实现。
class EventBus {constructor() {this.listeners {};}on(event, listener) {if (!this.listeners[event]) {this.listeners[event] [];}this.listeners[event].push(listener);}emit(event, data) {if (this.listeners[event]) {this.listeners[event].forEach(listener listener(data));}}off(event, listener) {if (this.listeners[event]) {this.listeners[event] this.listeners[event].filter(l l ! listener);}}
}const eventBus new EventBus();
eventBus.on(message, (data) console.log(Message received:, data));
eventBus.emit(message, Hello EventBus!);1.3 使用库如 PubSubJS
PubSubJS 是一个轻量级的 JavaScript 发布订阅库。
const PubSub require(pubsub-js);// 订阅
const token PubSub.subscribe(TOPIC, (msg, data) {console.log(msg, data);
});// 发布
PubSub.publish(TOPIC, Hello PubSubJS!);// 取消订阅
PubSub.unsubscribe(token);1.4 使用框架内置的状态管理工具
许多现代前端框架如 Vue.js、React 和 Angular 提供了内置的状态管理工具可以用来实现发布订阅模式。例如
Vue.js
const EventBus new Vue();// 组件A发布事件
EventBus.$emit(myEvent, Hello from Component A);// 组件B订阅事件
EventBus.$on(myEvent, (data) {console.log(data);
});React (使用 Context API 或 Redux)
// 使用 Context API
const MyContext React.createContext();// 提供者组件
const MyProvider ({ children }) {const [state, setState] useState(null);const publish (data) {setState(data);};return (MyContext.Provider value{{ state, publish }}{children}/MyContext.Provider);
};// 订阅者组件
const MySubscriber () {const { state, publish } useContext(MyContext);useEffect(() {console.log(State updated:, state);}, [state]);二、先后关系
可以先订阅后发布那可以先发布后订阅吗
在发布订阅模式中先订阅后发布是非常常见的做法因为这通常是实现实时事件通知的基本方式订阅者先准备好接收消息然后发布者发送消息。
然而某些情况下也可能需要在没有订阅者存在的情况下发布消息并且在订阅者稍后订阅时能够收到之前发布的消息。要实现这种“先发布后订阅”的机制可以采用以下几种方法
2.1 缓存事件数据
发布者在发布消息时将消息暂时存储在一个缓存中当新的订阅者订阅时可以将缓存中的消息发送给订阅者。
class EventBus {constructor() {this.listeners {};this.cachedEvents {};}on(event, listener) {if (!this.listeners[event]) {this.listeners[event] [];}this.listeners[event].push(listener);// 如果有缓存的事件立即触发if (this.cachedEvents[event]) {listener(this.cachedEvents[event]);}}emit(event, data) {if (this.listeners[event]) {this.listeners[event].forEach(listener listener(data));}// 缓存事件数据this.cachedEvents[event] data;}off(event, listener) {if (this.listeners[event]) {this.listeners[event] this.listeners[event].filter(l l ! listener);}}
}const eventBus new EventBus();// 发布事件
eventBus.emit(message, This is a cached message);// 订阅事件
eventBus.on(message, (data) {console.log(Message received:, data); // Output: This is a cached message
});2.2 使用 Redux 或 Vuex 等状态管理工具
在前端框架中使用状态管理工具例如 ReduxReact或 VuexVue.js可以在状态发生变化时订阅并触发相应的处理逻辑。状态管理工具的状态是持久的订阅者在任何时候都可以获取当前的状态。
Redux 示例
const { createStore } require(redux);// 定义 action 类型
const SET_MESSAGE SET_MESSAGE;// 定义 action 创建函数
const setMessage (message) ({type: SET_MESSAGE,payload: message
});// 定义 reducer
const messageReducer (state null, action) {switch (action.type) {case SET_MESSAGE:return action.payload;default:return state;}
};// 创建 Redux store
const store createStore(messageReducer);// 订阅 store
const unsubscribe store.subscribe(() {const state store.getState();console.log(State updated:, state);
});// 发布 action
store.dispatch(setMessage(This is a Redux message));2.3 使用本地存储或 IndexedDB
如果需要跨页面持久化数据可以使用浏览器的本地存储LocalStorage或 IndexedDB。发布者将消息存储到本地存储中订阅者在订阅时从本地存储中读取数据。
// 发布消息
localStorage.setItem(message, This is a persisted message);// 订阅消息
const cachedMessage localStorage.getItem(message);
if (cachedMessage) {console.log(Message received:, cachedMessage);
}通过这些方法可以实现“先发布后订阅”的功能确保订阅者能够收到之前发布的消息。选择哪种方法可以根据具体需求和技术栈来决定。