前端如何实现单例模式

如果开发一个前端组件,在这个组件里,要发起一个 websocket 请求。但是这个组件又有可能需要复用。不可能每创建一个组件都发起一个 websocket 请求,所以这个 websocket 请求最好是可以复用。这个方案应该如何设计呢

为了设计一个可以复用的 WebSocket 请求,避免每次创建组件时都重新发起请求,你可以采用单例模式(Singleton Pattern)来管理 WebSocket 连接。以下是一个可能的设计方案:

1. 创建一个 WebSocket 管理器

首先,创建一个 WebSocket 管理器类,该类负责管理 WebSocket 连接的创建和复用。

class WebSocketManager {
  private static instance: WebSocketManager;
  private socket: WebSocket | null = null;
  private url: string;

  private constructor(url: string) {
    this.url = url;
  }

  public static getInstance(url: string): WebSocketManager {
    if (!WebSocketManager.instance) {
      WebSocketManager.instance = new WebSocketManager(url);
    }
    return WebSocketManager.instance;
  }

  public connect(): WebSocket {
    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
      this.socket = new WebSocket(this.url);
      this.socket.onopen = () => console.log("WebSocket connected");
      this.socket.onclose = () => console.log("WebSocket closed");
      this.socket.onerror = error => console.error("WebSocket error", error);
      this.socket.onmessage = event =>
        console.log("WebSocket message", event.data);
    }
    return this.socket;
  }
}

2. 在组件中使用 WebSocket 管理器

在组件中,通过 WebSocket 管理器来获取 WebSocket 实例。

import { defineComponent, onMounted, onUnmounted } from "vue";
import WebSocketManager from "./WebSocketManager";

export default defineComponent({
  name: "WebSocketComponent",
  setup() {
    const url = "wss://example.com/socket";
    const webSocketManager = WebSocketManager.getInstance(url);
    let socket: WebSocket | null = null;

    onMounted(() => {
      socket = webSocketManager.connect();

      socket.onmessage = event => {
        console.log("Message from server:", event.data);
      };
    });

    onUnmounted(() => {
      if (socket) {
        socket.close();
      }
    });

    return {};
  },
});

3. 处理多个组件的订阅

为了确保多个组件可以订阅 WebSocket 消息,你可以在 WebSocketManager 中添加事件分发逻辑。

import { EventEmitter } from "events";

class WebSocketManager extends EventEmitter {
  private static instance: WebSocketManager;
  private socket: WebSocket | null = null;
  private url: string;

  private constructor(url: string) {
    super();
    this.url = url;
  }

  public static getInstance(url: string): WebSocketManager {
    if (!WebSocketManager.instance) {
      WebSocketManager.instance = new WebSocketManager(url);
    }
    return WebSocketManager.instance;
  }

  public connect(): WebSocket {
    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
      this.socket = new WebSocket(this.url);
      this.socket.onopen = () => console.log("WebSocket connected");
      this.socket.onclose = () => console.log("WebSocket closed");
      this.socket.onerror = error => console.error("WebSocket error", error);
      this.socket.onmessage = event => this.emit("message", event.data);
    }
    return this.socket;
  }
}

在组件中订阅消息:

import { defineComponent, onMounted, onUnmounted } from "vue";
import WebSocketManager from "./WebSocketManager";

export default defineComponent({
  name: "WebSocketComponent",
  setup() {
    const url = "wss://example.com/socket";
    const webSocketManager = WebSocketManager.getInstance(url);

    const handleMessage = (message: any) => {
      console.log("Message from server:", message);
    };

    onMounted(() => {
      webSocketManager.connect();
      webSocketManager.on("message", handleMessage);
    });

    onUnmounted(() => {
      webSocketManager.off("message", handleMessage);
    });

    return {};
  },
});

这种设计确保了 WebSocket 连接可以在多个组件之间复用,并且每个组件都可以订阅 WebSocket 消息。通过使用事件发射器(EventEmitter),消息的分发和订阅变得更加灵活和高效。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值