Tìm kiếm trang web

angular - Javascript, cần giải pháp cho vấn đề bất đồng bộ


Hiện tại đang tạo một ứng dụng sử dụng Angular, socket.io và express. Tuy nhiên, tôi gặp phải một vấn đề bất đồng bộ mà tôi gặp khó khăn trong việc tìm giải pháp. Đây là mã:

  export class WebsocketService {

  this.socket;

  public connect() {
    const token = sessionStorage.getItem('token');
    this.socket = io('http://localhost:3000', { query: { token: token } });
  }

  public getSocket () {

      // this function should only return this.socket when it is available

      return this.socket;

  }

Ý tưởng là trước tiên ở đâu đó trong ứng dụng có một kết nối với websocket, các hàm io do đó được gọi một lần:

    this.socket = io('http://localhost:3000', { query: { token: token } });

Sau đó trong phần còn lại của ứng dụng, thuộc tính this.socket nên được truyền đi khắp nơi. Tuy nhiên, this.socket luôn phải trả về đối tượng và sẽ chờ đối tượng đó nếu nó chưa có.

Việc triển khai cũng nên xử lý các phần khác của ứng dụng cố gắng gọi getSocket và nhận về undefined. Về cơ bản, getSocket không bao giờ nên trả về undefined, nó nên chờ kết nối và sau đó trả về this.socket.

Tôi đã thử nghịch với các promise một chút nhưng dường như tôi không thể tìm ra một giải pháp tinh tế.

Câu trả lời #1

Tôi không biết tại sao bạn cần phương thức connect, nhưng đây là một cách tiếp cận

export class WebsocketService {

  getSocket() {

    // this function should only return this.socket when it is available

    if (!this.socket || (this.socket && this.socket.disconnected)) {

      this.socket = new Promise((resolve, reject) => {

        const token = sessionStorage.getItem('token');
        const s = io('http://localhost:3000', { query: { token: token } });

        s.on('connect', () => {
          console.log(socket.connected); // true
          resolve(s);
        });

        s.on('disconnect', () => {
          console.log(socket.disconnect); // true
          reject(s);
        });
      });
    }

    return this.socket;
  }
}

Sau đó, cách sử dụng là:

service.getSocket().then(socket => {
    // Use the socket
});

Hoặc với async/await:

const socket = await service.getSocket();
// Use the socket

Câu trả lời #2

export class WebsocketService {
    this.socket = io('http://localhost:3000', { query: { token: token }})
    public getSocket () {
        return new Promise((res) => {
           while (!this.socket.connected) {}
           res(this.socket)
        })
    }
}

sau đó gọi: service.getSocket().then((socket) => {})

Chỉ cung cấp cho bạn ổ cắm khi nó đã được kết nối. Điều này giả định rằng ổ cắm sẽ có thể kết nối lại, nhưng một số lỗi có thể xảy ra nếu không bao giờ kết nối lại được.