Javascript WebSocket响应函数执行

Javascript WebSocket响应函数执行,javascript,function,asynchronous,websocket,execution,Javascript,Function,Asynchronous,Websocket,Execution,我有一个代码,但是问题是函数getip()没有首先执行。我没有太多的Javascript代码,所以我不知道到底发生了什么。我希望函数getip()完全完成后执行控制台.log('connected!') 如果可能的话,我希望有人能做出必要的改变,并做一些简要的解释 (async function getip() { var responses = []; var ips = [ "IP1", "IP2" ] var length =

我有一个代码,但是问题是
函数getip()
没有首先执行。我没有太多的Javascript代码,所以我不知道到底发生了什么。我希望
函数getip()
完全完成后执行
控制台.log('connected!')

如果可能的话,我希望有人能做出必要的改变,并做一些简要的解释

(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(){
var响应=[];
变量ips=[“IP1”,“IP2”]
var length=ips.length
对于(变量i=0;i
发生了两件事:

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

你的
承诺
不会在任何地方调用
res
。这意味着承诺永远不会兑现,因此,你的等待永远不会停止

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

使用
onopen
onerror
事件监视web套接字是否已成功打开或何时发生错误。在
onopen
函数调用
resolve
以成功关闭承诺。在
onerror
回调
reject
中,拒绝承诺并向其传递一些数据,以便您可以读取错误日志。在这两种情况下,请清除超时

不要等待-等待每个承诺,而是将所有承诺收集到一个数组中,并使用其中一个来等待承诺数组。这将确保并行打开所有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;
}

你能解释一下你为什么要那样吗?因为这正是
async
的发展方向。删除
async
会使
getit()
函数同步,但其中运行的代码仍然使用承诺,承诺是继承异步的。建立连接,就像使用插座一样,可能需要(相对而言)一段时间。因此,允许其他代码在等待时运行是一个很好的策略。我已经编辑了答案并删除了iLife以显示您应该使用此功能。请随时提出更多问题。:)我正在尝试在网络上创建一个控制台界面,它将连接到我计算机上的一组虚拟机。因此,我需要确保它在控制台显示任何命令之前连接,并且命令不起作用;)好了,给你。连接到虚拟机,等待连接建立,然后显示控制台。异步部分确保同一线程上的所有其他代码在该时刻发生之前不会被阻塞。它让你控制加载完成后要做什么。我试着做出另一个承诺唯一的问题是现在函数完成后什么都没有执行。
getip().then(sockets => {
  console.log('connected!', sockets);
}).catch(error => {
  console.log(error);
});