admin管理员组

文章数量:1431927

When I look at tutorials/documentation about WebSockets I find code like this:

var ws = new WebSocket("ws://localhost:8765/dlt");
ws.onopen = () => {
  // do some very important stuff after connection has been established
  console.log("onopen");
}

But what about race conditions here? Are there somehow avoided in JavaScript?

For example this code (which just assigns onopen after the connection has been opened) will fail:

var ws = new WebSocket("ws://localhost:8765/dlt");
setTimeout(() => {
  ws.onopen = () => {
    // do some very important stuff after connection has been established
    console.log("onopen"); ///  <== won't be called
  }
}, 100);

Can I be sure that the assignment has been done before the connection get's established?

(I tried to extend WebSocket with a custom onopen() method but this doesn't seem to work)

class MyWebSocket extends WebSocket {
  onopen() {
    console.log("onopen()");
    /// do some very important stuff after connection has been established
  }
}

When I look at tutorials/documentation about WebSockets I find code like this:

var ws = new WebSocket("ws://localhost:8765/dlt");
ws.onopen = () => {
  // do some very important stuff after connection has been established
  console.log("onopen");
}

But what about race conditions here? Are there somehow avoided in JavaScript?

For example this code (which just assigns onopen after the connection has been opened) will fail:

var ws = new WebSocket("ws://localhost:8765/dlt");
setTimeout(() => {
  ws.onopen = () => {
    // do some very important stuff after connection has been established
    console.log("onopen"); ///  <== won't be called
  }
}, 100);

Can I be sure that the assignment has been done before the connection get's established?

(I tried to extend WebSocket with a custom onopen() method but this doesn't seem to work)

class MyWebSocket extends WebSocket {
  onopen() {
    console.log("onopen()");
    /// do some very important stuff after connection has been established
  }
}
Share Improve this question asked Nov 28, 2018 at 12:01 fransfrans 9,84814 gold badges71 silver badges164 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

You should have a read about javascript's event loop: https://developer.mozilla/en-US/docs/Web/JavaScript/EventLoop#Event_loop

If you look at the section about Run-to-pletion, you get this useful explanation:

Each message is processed pletely before any other message is processed. This offers some nice properties when reasoning about your program, including the fact that whenever a function runs, it cannot be pre-empted and will run entirely before any other code runs (and can modify data the function manipulates). This differs from C, for instance, where if a function runs in a thread, it may be stopped at any point by the runtime system to run some other code in another thread.

So in your example, the assignment to ws.onopen must be pleted before the websocket does anything asynchronous in nature. By putting your assignment inside setTimeout, you are moving it outside of the currently running context, and so it may not be executed before it is required by the websocket.

You should rest assured that the example is ok. The Javascript event loop will finish the current task before assuming any other tasks. This means that 1) the WebSocket cannot open the connection (async operation) before the onopen event, 2) the onopen event handler will be called during the following cycles.

Setting the timeout on the other hand will plicate matters, because the events will be called in some order after the current task. This means that that the WebSocket has chance to open the connection before the handler has been set.

本文标签: javascriptHow to avoid race conditions when assigning custom methods to WebSocketStack Overflow