简体   繁体   中英

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

The popular JavaScript module Q implements the deferred / promise / futures concept. I think it's mainly used with node.js but it support browser use as well. I'm using it with node.js.

To do sequential calls you chain one promise to the next using then() but in a loop it can be so counterintuitive than I'm finding it difficult to do the same as this pseudocode:

forever {
    l = getline();

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

The Q documentation includes an example which 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 in trying many ways to adapt this example to my problem I'm having no success at all.

Unlike in the example code I'm not iterating over an array but wish to loop until an end condition is met. Also I always call the same function. My function does not take the previous result as a parameter to the next call. Each call takes no arguments but the return value decides whether to continue the loop.

These seemingly trivial differences are causing some kind of insurmountable mental block. Now I can see why many people have trouble understanding promises.

The key thing to remember is that if you return a promise from a then callback, then it will replace the existing promise. The idea is that after executing one iteration of whatever chain of things you want to do in the loop body, you either return a value, which will resolve the promise, or you return a new promise that will execute the body of the loop 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);
    });
}

This isn't specific to Q: Synchronous for loop .

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