简体   繁体   English

JavaScript 中的事件计时

[英]Event timing in JavaScript

I am connecting to a web socket server from my web page, and sending click events to the server through this.我正在从我的网页连接到 Web 套接字服务器,并通过它向服务器发送点击事件。

In my click routine, I am doing在我的点击例程中,我正在做

if (socket.readyState === WebSocket.OPEN) {
  //send
}else {
  msgsArray.push(messages)
}

Then in socket.onOpen, I post all the messages from msgsArray using shift();然后在 socket.onOpen 中,我使用 shift() 发布来自 msgsArray 的所有消息;

But there seems to be a possible race condition, if the socket is opened after I've check that the web socket isn't open but before I've added the message to the array.但是似乎存在可能的竞争条件,如果在我检查 Web 套接字未打开之后但在将消息添加到数组之前打开套接字。

Is there actually no race condition because JavaScript is single-threaded?因为 JavaScript 是单线程的,所以实际上没有竞争条件吗? If not, is there any way for me to make this "thread"-safe?如果没有,我有什么办法可以使这个“线程”安全? Is it guaranteed that onOpen will only be called after my click event processing is finished?是否保证只有在我的点击事件处理完成后才会调用 onOpen?

--- Update --- - - 更新 - -

The race condition I am referring to is where socket.readyState is not OPEN where I'm checking it, but it becomes OPEN and socket.onopen is called before I add the message to the array.我所指的竞争条件是 socket.readyState 在我检查它的地方不是 OPEN,但它变成 OPEN 并且在我将消息添加到数组之前调用 socket.onopen 。 But actually I don't think that can happen, can it?但实际上我认为这不可能发生,是吗? onopen can't be called before the click routine finishes up, right?在单击例程完成之前不能调用 onopen ,对吗? But what about the opposite, where socket.readyState is OPEN, but closes right as I am writing to it?但是相反的情况呢,socket.readyState 是 OPEN,但在我写信时就关闭了? I will add try catch around that and add it to the array in the catch block.我将围绕它添加try catch并将其添加到 catch 块中的数组中。 I think this should handle all possible situations.我认为这应该处理所有可能的情况。 If not, can you advise?如果没有,你能建议吗?

After reading the documentation on WebSocket.send, I updated my code to be completely "race-safe"阅读有关 WebSocket.send 的文档后,我将代码更新为完全“种族安全”

  //Obj.socketMessagesToSend is a JS array ([])
  if (Obj.socket && Obj.socket.readyState === WebSocket.OPEN) {
    try {
      Obj.socket.send(JSON.stringify(report));
    } catch (e) {
      Obj.socketMessagesToSend.push(JSON.stringify(report));
      Obj.connectToWebSocket();
    }
  } else {
    Obj.socketMessagesToSend.push(JSON.stringify(report));
    Obj.connectToWebSocket();
  }

And

Obj.connectToWebSocket() = function() {
  if (Obj.socket && (Obj.socket.readyState === WebSocket.CONNECTING || Obj.socket.readyState === WebSocket.OPEN)) return;
  if (typeof Config.WebSocketInfo != 'object') return;
  if (!Config.WebSocketInfo.enabled) return;

  try {

    Obj.socket = new WebSocket(Config.WebSocketInfo.url);
    Obj.socket.onmessage = Obj.socketOnMessage;
    Obj.socket.onopen = function(e) {
//      console.log("Web Socket Connection established!");
      while (Obj.socketMessagesToSend.length != 0) {
        Obj.socket.send(Obj.socketMessagesToSend.shift());
      }
    }
  } catch (e) {
    console.log('Could not connect. Is connection blocked by your content-security-policy?');
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM