观察者模式和发布订阅模式

文章目录

观察者模式

Subject 和 Observer 直接绑定,中间无媒介。如点击事件,事件直接和按钮进行绑定。

发布订阅模式

Publisher 和 Observer 相互不认识,中间有媒介。如在 A 组件中绑定一个事件,在 B 组件中触发这个事件,这个两个组件相隔十万八千里互补认识,那么就通过中间event这个媒介来通讯。

发布订阅模式需要在代码中触发 emit ,而观察者模式没有 emit

手写观察者模式

jsx 复制代码
import React, { useState, useEffect } from 'react';

// 观察者函数
const observer = (newValue) => {
  console.log(`Subject changed to ${newValue}`);
};
const SubjectComponent = () => {
  // 使用useState创建一个状态变量
  const [subject, setSubject] = useState('Initial Value');
  // 使用useEffect来模拟观察者模式
  useEffect(() => {
    // 当subject变化时,调用观察者函数
    observer(subject); 
  }, [subject]); // 依赖数组中包含subject,这样每当subject变化时,useEffect都会执行
  // 更新subject的方法
  const updateSubject = () => {
    setSubject('Updated Value');
  };
  return (
    <div>
      <p>Subject: {subject}</p>
      <button onClick={updateSubject}>Update Subject</button>
    </div>
  );
};

export default SubjectComponent;

手写发布订阅模式

jsx 复制代码
// EventBus.js
import { createContext, useContext, useState } from 'react';

const EventBusContext = createContext();

export const EventBusProvider = ({ children }) => {
  const [events, setEvents] = useState({});

  const subscribe = (eventName, callback) => {
    if (!events[eventName]) {
      setEvents((prevEvents) => ({
        ...prevEvents,
        [eventName]: [],
      }));
    }
    setEvents((prevEvents) => ({
      ...prevEvents,
      [eventName]: [...prevEvents[eventName], callback],
    }));
  };

  const publish = (eventName, data) => {
    if (events[eventName]) {
      events[eventName].forEach((callback) => callback(data));
    }
  };

  return (
    <EventBusContext.Provider value={{ subscribe, publish }}>
      {children}
    </EventBusContext.Provider>
  );
};

export const useEventBus = () => useContext(EventBusContext);
相关推荐
wuhen_n10 分钟前
ESLint + Prettier + Husky + lint-staged:建立自动化的高效前端工作流
前端·javascript·vue.js
小同志0011 分钟前
HTML 基础
前端·javascript·html
wuhen_n2 小时前
网络请求在Vite层的代理与Mock:告别跨域和后端依赖
前端·javascript·vue.js
用头发抵命11 小时前
Vue 3 中优雅地集成 Video.js 播放器:从组件封装到功能定制
开发语言·javascript·ecmascript
蓝冰凌11 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛12 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉12 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
TON_G-T13 小时前
day.js和 Moment.js
开发语言·javascript·ecmascript
Irene199113 小时前
JavaScript 中 this 指向总结和箭头函数的作用域说明(附:call / apply / bind 对比总结)
javascript·this·箭头函数