简体   繁体   中英

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.

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();

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.

Is there actually no race condition because JavaScript is single-threaded? 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?

--- 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. But actually I don't think that can happen, can it? onopen can't be called before the click routine finishes up, right? But what about the opposite, where socket.readyState is OPEN, but closes right as I am writing to it? I will add try catch around that and add it to the array in the catch block. 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"

  //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?');
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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