Javascript,异步问题所需的解决方案

Javascript,异步问题所需的解决方案,javascript,angular,typescript,asynchronous,es6-promise,Javascript,Angular,Typescript,Asynchronous,Es6 Promise,当前正在使用Angular、socket.io和express创建应用程序。然而,我遇到了一个异步问题,我很难找到解决方案。代码如下: export class WebsocketService { this.socket; public connect() { const token = sessionStorage.getItem('token'); this.socket = io('http://localhost:3000', { query: { to

当前正在使用Angular、socket.io和express创建应用程序。然而,我遇到了一个异步问题,我很难找到解决方案。代码如下:

  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;

  }
其思想是,首先在应用程序中某个地方与websocket连接一次,因此io函数被称为一次:

    this.socket = io('http://localhost:3000', { query: { token: token } });
然后在应用程序的其余部分中,应该传递
this.socket
属性。但是,
this.socket
应始终返回该对象,如果该对象不存在,则应等待该对象

该实现还应该处理应用程序中试图调用
getSocket
并返回未定义的其他部分。基本上,getSocket永远不应该返回未定义的,它应该等待连接,然后返回this.socket


我试着玩弄一些承诺,但我似乎找不到一个优雅的解决方案。

我不知道为什么你需要
connect
方法,但这里有一种方法

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;
  }
}
那么,用法是:

service.getSocket().then(socket => {
    // Use the socket
});
或使用异步/等待:

const socket = await service.getSocket();
// Use the socket
然后调用:
service.getSocket()。然后((socket)=>{})


只有当插座连接时才给你。这假设套接字能够重新连接,但如果永远无法重新连接,则可能会出现一些错误。

您的意思是承诺应该等待有人调用服务上的
connect()
?如果
io
立即返回套接字(如上面代码中所示),您为什么需要承诺?只要按需构造它(或者在
连接中,如果您愿意)并根据需要返回它…?io是异步的,因此不会立即返回return@WillemvanderVeen-嗯,你的代码对待它就像对待它一样。忙碌的等待从来都不是一个好主意。在主UI线程(Angular运行的地方)上基于浏览器的JavaScript代码中,它们是一个特别糟糕的主意!此.socket.connected
不是经常计算的。但是,代码执行没有被阻止,因为这是一个承诺。我写这篇文章时对API了解很少,但据我所知,套接字对象在失去连接时会尝试无限次地重新连接。如果无法重新连接,则需要进行一些错误处理。“但是,代码执行不会因为承诺而被阻止。”不,承诺不是这样工作的。承诺用于观察异步完成。它们不会使某些东西同步或异步。您的
getSocket
将永远不会返回,锁定浏览器的UI。如果
this.socket.connected
在时间开始时为false,则
this.socket.connected
在可变秒数后为true,这是异步事件的代理。谢谢,我不明白“繁忙等待”会阻止所有其他执行。我想当我学习这个构造时,我会被指示在循环中设置一个睡眠或超时,忘记了它,它就会中断。
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)
        })
    }
}