Creating a synchronous loop from synchronous callbacks with module node.js + Q deferred / promises

The popular JavaScript Q module implements the concept of deferred / promises / futures. I think it is mainly used with node.js, but it also supports browser. I use it with node.js.

To make consecutive calls, you bind one promise of the following with then() , but in a loop it can be so inconsistent that I find it difficult to do the same thing as this pseudocode:

 forever { l = getline(); if (l === undefined) { break; } else { doStuff(l); } } 

The Q documentation includes an example that seems pretty similar:

 var funcs = [foo, bar, baz, qux]; var result = Q.resolve(initialVal); funcs.forEach(function (f) { result = result.then(f); }); return result; 

But trying to adapt this example to my problem, I did not succeed.

Unlike the sample code, I do not iterate over the array, but I want to loop until the end condition is met. Also, I always call the same function. My function does not accept the previous result as a parameter for the next call. Each call takes no arguments, but the return value decides whether to continue the loop.

These seemingly trivial differences cause some kind of insurmountable mental block. Now I understand why many people find it difficult to understand promises.

+4
source share
2 answers

The main thing to remember is that if you return the promise from the then callback, it will replace the existing promise. The idea is that after doing one iteration of any chain of things that you want to do in the body of the loop, you either return a value that will resolve the promise, or you will return a new promise that will fulfill the loop body again.

 function iterateUntil(endValue){ // This line would eventually resolve the promise with something matching // the final ending condition. return Q.resolve('some value') .then(function(value){ // If the promise was resolved with the loop end condition then you just // return the value or something, which will resolve the promise. if (value == endValue) return value; // Otherwise you call 'iterateUntil' again which will replace the current // promise with a new one that will do another iteration. else return iterateUntil(endValue); }); } 
+6
source

This does not apply to Q: Synchronous for loop .

0
source

All Articles