This was a solution to the situation where you had an asynchronous task of want to perform over and over again, in a non- Blocking fashion, stopping when some condition was met.
To set the stage, I'll be using the Bluebird Promise Library, the best Promise library I ' ve used.
First, we ll construct the Promise function which would do the looping:
varPromise = require (' Bluebird '));varPromisewhile =function(condition, action) {varResolver =Promise.defer (); varloop =function() { if(!condition ())returnResolver.resolve (); returnPromise.cast (Action ()). then (Loop).Catch(Resolver.reject); }; Process.nexttick (loop); returnresolver.promise;};
It receives 2 arguments, both expected to be functions:
condition
-a predicate function which shall return true
or false
indicate whether the end state has been reached. if done, false
otherwise.
action
-The async task to being performed, which itself should return a Promise.
A couple things to note:
- I simulated the async task with a simple
setTimeout
would is optimal for looping over Database calls, HTTP requests, O R anything else requiring latency.
- We use a function for the condition which allows us to do any manner of interesting tests for completion.
- We utilize to
process.nextTick
wait until the next CPU cycle before starting. If we don ' t do this, it'll complete immediately and would not "loop."
- You'll see it's actually using recursion for the iteration, but behaves like a while loops hence the title with the word " While Loop ' in quotes. But it does follow a while loop-esque format of the condition, action, looping until condition is met.
What follows is a sample usage of the promiseWhile()
function.
//And below is a sample usage of this promisewhile functionvarsum = 0, Stop= 10;p Romisewhile (function() { //Condition for stopping returnSum <stop;},function() { //Action to run, should return a promise return NewPromise (function(Resolve, reject) {//arbitrary 250ms Async method to simulate async process //In real usage it could just is a normal async event that //returns a Promise.SetTimeout (function() {sum++; //Print out the sum thus far to show progressconsole.log (sum); Resolve (); }, 250); });}). Then (function() { //Notice We can chain it because it s a Promise, //This would run after completion of the promisewhile promise!Console.log ("Done");});
And that ' s it!
I threw the whole gist on GitHub
Feel free to e-mail me or Tweet me @victorquinn with any questions!
Javascript:async Promise "while loop"