简体   繁体   中英

Javascript / Node.js threading

I have this piece of code, a function that has a callback on finish that changes the global go to true. And a loop that checks go, and goes on.

var go;

function (doSomething, callback) {
  //callback is called after 1 sec.
}

function callBack() {
  go = true;
}

while(true) {
  if (go) {
    break;
  } 
}

My problem / question is: will the callback ever have chance to set the 'go' global? It looks like in my tests, the while loop is blocking every other possible executions. Is this what JavaScript / NodeJS does?

Short answer: No. The callback will never be executed since you are blocking the thread. The program will be infinitely unresponsive.

NodeJS is effectively single-threaded; all long-running operations, I/O etc should be asynchronous (under the hood this usually means performing the actual time-consuming work on a worker thread or similar, but that's not really visible from the client code).

To have an event loop or blocking code like in your example will not work in such an environment (indeed, the environment itself already supplies the event loop). You should likely re-design your code to work asynchronously. Instead of looping and waiting for go to become true, you could run whatever code depends on go being true in the callback (which likely means you don't need the go flag in the first place, globals are rarely a good choice for these types of things).

There are mechanisms to spawn worker threads, child processes etc if needed, but that's not really applicable in the simple illustrative case shown in your example.

EDIT: You mentioned your issue is really how to synchronize two different conditions, and execute code once both are fulfilled. With "vanilla" javascript you could of course have two flags, each set by its corresponding callback, and the callback would also both call a function that verifies all needed conditions. Such as:

var flag1 = false;
var flag2 = false;

func1(someParam, function() {
  flag1 = true;
  checkFlags(); 
});

func2(someParam, function() {
  flag2 = true;
  checkFlags(); 
});

function checkFlags() {
  if (flag1 && flag2) {
    // both functions have completed, the callbacks have executed
    // and set both flags. Now go ahead and do stuff.
  }
}

With this code, it doesn't matter if func1 or func2 completes and invokes its callback first, since both callbacks with call checkFlags() which will make sure both flags are set. Since all code will run in the same thread there is also no need for further concurrency related synchronization.

There are also more advanced mechanisms available for these types of things. A common technique is to use Promises. Promises enable simple chaining of multiple asynchronous calls, either in series or in parallel, and supports synchronizing multiple function calls into one common result, as well as providing a ton of other useful stuff. Using promises however require your functions to support it; instead of taking one or many callback functions as parameters, functions should return promise objects. Many frameworks use promises out of the box.

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