微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebSocket 响应函数执行

如何解决WebSocket 响应函数执行

我有一个代码,但是它的问题是 function getip() 没有先执行。我没有用 Javascript 编写太多代码,所以我真的不知道发生了什么。我希望在 console.log('connected!') 完全完成后执行 function getip()

如果可能的话,如果有人能够进行必要的更改并提供一些简短的解释,我将不胜感激。

(async function getip() {
    var responses = [];
    var ips = [ "IP1","IP2" ]
    var length = ips.length
    for (var i = 0; i < length; i++) {
        (async function() {
            var ws = new WebSocket('ws://' + ips[i] + ':80');
            await new Promise(function(res) {
                var timeout = setTimeout(function() {
                                console.log("Socket connection timeout",ws.readyState);
                                console.log(ws.url);
                                if (ws.readyState == 3){
                                    responses.push('connected')
                                } else {
                                    responses.push('not connected')
                                }
                                ws.close();
                },5000);
            });
        })();
    }
})();

console.log('connected!')

解决方法

发生了一些事情:

getip 函数是异步的,这意味着它在执行时不会阻止其他代码运行。由于异步性质,这会导致调用 console.log('connected')

您的 Promise 不会在任何地方调用 res。这意味着承诺永远不会解决,因此,您的 await 永远不会停止等待。

在您的承诺的 setTimeout 中,您正在寻找网络套接字实例上的 readyState。目前您正在检查的是该状态是否为 3,这意味着关闭,它(可能)不是,因为您刚刚打开了网络套接字。相反,关闭连接并拒绝承诺,说承诺失败。

使用 onopenonerror 事件来监控网络套接字是否已成功打开或何时发生错误。在 onopen 函数中调用 resolve 以成功关闭承诺。在 onerror 回调 reject 中,promise 并将一些数据传递给它,以便您可以读取错误日志。在这两种情况下,清除超时。

不是对每个 await 进行 Promise-ing,而是将它们全部收集在一个数组中,并使用 Promise.all() 来等待承诺数组。这将确保所有 Web 套接字并行打开。当一切顺利时,console.log('connected') 将登录到控制台。否则,如果其中一个承诺产生了错误,它将记录一个错误。

这个主题很难掌握,需要一些练习才能获得点击时刻。

以下示例使用了上述所有做法。检查它,如果您有任何后续问题,请随时提出。

async function getip() {
  const ips =  ["IP1","IP2"];
  const responses = ips.map(ip => new Promise((resolve,reject) => {
    const ws = new WebSocket(`ws://${ip}:80`);
    
    let timeout = setTimeout(() => {
      // Save the state before closing,otherwise it will always be the closed state.
      const currentState = ws.readyState;
      ws.close();
      reject({
        message: 'Socket connection timeout',state: currentState
      });
    },5000);

    ws.onopen = () => {
      clearTimeout(timeout);
      resolve(ws);
    };

    ws.onerror = event => {
      clearTimeout(timeout);
      reject({
        message: 'Socket connection error',event
      });
    };
  }));

  const sockets = await Promise.all(responses);
  return sockets;
}
getip().then(sockets => {
  console.log('connected!',sockets);
}).catch(error => {
  console.log(error);
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。