Skip to content Skip to sidebar Skip to footer

Asynchronous Function In A While-loop

I have a question about how to perform an asynchronous task in a while-loop until some condition is met. This is more of a theoretical question but I can see how this could be an i

Solution 1:

In javascript, you cannot loop waiting for a condition to change unless the code that actually changes the condition is inside that very loop or a side effect of some function called in the loop. That's because javascript is single threaded (except for webworkers which aren't being considered here) so as long as a loop is looping in javascript, no other code can run so no other code can ever change your condition variable. You will simply have an infinite loop as the loop waits for something that can never change. Eventually the browser will complain that you have unresponsive code running and shut it down.

Because of that, there aren't indeterminate or long wait loops in javascript. It is possible to loop for a second or so just to let some time pass, but that's rarely useful, productive or the best way to write JS code.

Instead, you have to either trigger an event or callback when the condition changes and the interested code can subscribe to that event or register its callback. Or, you have to poll on a timer to see what the condition has changed (the first option is the preferred choice).


If you were designing an API where you wanted to be able to allow some calling code to know when a state changes, usually you would implement either a callback or a promise. The callback approach could look like this:

device.registerStateChangeCallback("type of state interested in", fn);

Then, the API will call the passed in callback function whenever the specified state changes to a new value. It's up to the API whether this is a one-time notification or whether it happens every time the state changes until the callback is deregistered.

So, rather than having the caller wait in a busy loop until the state changes, the caller writes async code (this is how javascript works for this kind of stuff) with a callback that will be called sometime later when the state changes. For example, a caller's code might look like this:

device.registerStateChangeCallback("syncState", function(newState) {
     // caller puts code here that wants to do something when // the syncState has changed
});

If the notifications are meant to be one time only, then you could also use promises and the API simply returns a promise that is resolved when the syncState changes:

device.registerStateChange("syncState").then(function(newState) {
     // caller puts code here that wants to do something when // the syncState has changed
});

The disadvantages of promises are that they are purely single use (one notification only) so if you want multiple notifications, then better to use callbacks. The advantages of promises over callbacks is that they provide a lot of features for synchronizing them with other events (such as sequencing, waiting for a series of events to all finish, coordinating multiple async things, etc...) and they provide better async error handling.

Solution 2:

You can't do this. The reason is that Javascript is single-threaded. While the while loop is running, nothing else runs, so whatever asynchronous task is expected to update the device state will never get a chance to run. Asynchronous tasks in Javascript are run by the main event handler loop. This means that asynch operations won't run until you return from your script back to the event handler, or the script performs a call into the event handler (this only happens when the script waits for user input with confirm or prompt).

Solution 3:

This is indeed a very theoretical question. It would be quite weird to have an async API to get a current status. You would most probably have either:

  • a sync method that gives you the current status;
  • or an async method that would call you back when the status changes. In that case, no need to loop, you just wait for the callback.

But if you do have a specific example of such an API, let us know...

Solution 4:

This function uses setTimeout so the callback returns without recursion. The requirement is that your environment implement a setTimeout mechanism, as this is not part of JavaScript.

var callback = functioncallback(result){
   if(result == "some condition"){
       //done
   } else {
       setTimeout(device.getStateAsync(callback), 10);
   }
}

device.getStateAsync(callback);

Solution 5:

I know this is coming late but es6 has provided a better way to do this. The solution lies in using Generators + Promises.

Take a look at this repository where I had to create Twitter threads where the preceding tweet has to be in reply to the previous and using and this is done by fetching the current tweet's ID and using that to post the next tweet.

Look here => https://github.com/Udokah/tweet-threader

Post a Comment for "Asynchronous Function In A While-loop"