WebSocket仅在循环完成后才发送消息

时间:2012-10-27 03:57:54

标签: javascript websocket

我有一个如下代码:

var ws = new WebSocket("ws://localhost");
ws.onopen = function() {
    // Long running loop
    for (var i = 0; i < 1000000; i++) {
        ws.send(i);
        console.log(i);
    }
};

在循环完成后,服务器只接收消息(或者我相信客户端只开始发送消息)。为什么会这样?

2 个答案:

答案 0 :(得分:2)

页面执行的一些区域是:

  • 的JavaScript
  • DOM渲染
  • 网络

我暂时没有对此进行测试,但我认为仍然如此,如果您执行一个函数(或在一个范围内运行代码),那么如果您调用更新DOM或make在当前范围存在之前不会发生的网络请求。

e.g。

function doSomething() {
  document.body.innerHTML += 'hello';
  var ws = new WebSocket('ws://my-websocket-endpoint.com');
  ws.onopen = function() { alert( 'awesome!' ); };
}

doSomething();

在上面的代码中会发生以下情况:

    执行
  • doSomething并运行内部代码。
  • doSomething返回并且范围发生变化
  • 'hello'然后出现在DOM中,因为浏览器为UI线程提供了运行任何挂起更新的机会
  • 建立WebSocket连接
  • 可能需要一段时间,直到alert开火。

特别关注WebSocket示例。如果你考虑一下我们在创建WebSocket实例后可以添加事件处理程序的事实,这意味着一旦我们调用构造函数就不会发生连接。仅在当前执行范围完成时才尝试连接。我无法100%确认这一点,但WebSocket.send函数实际上发送任何数据的可能性极小,直到执行范围完成为止。

var ws = new WebSocket('ws://my-websocket-endpoint.com');

function sendStuff() {
  for( var i = 0; i < 10000; ++i ) {
    ws.send( i );
  }
}

// Assume we are connected
sendStuff();

在上面的代码中,我希望:

    要调用
  • sendStuff,运行循环并退出
  • 浏览器然后处理任何待处理的事情,包括网络活动。这包括实际发送数据

答案 1 :(得分:1)

它没有回答您的问题,但值得注意的是您的代码看起来不正确。

您的new WebSocket调用会启动与服务器的异步握手。完成后,您在websocket上注册的任何onopen回调都将运行。只有在这个时候,您才能拨打ws.send并希望服务器接收您的消息。

然后你可以将你的例子改写为

var ws = new WebSocket("ws://localhost");
ws.onopen = function() {
    for (var i = 0; i < 1000000; i++) {
        ws.send(i);
        console.log(i);
    }
};