While loop using bluebird promises

Brian Keith picture Brian Keith · Mar 31, 2015 · Viewed 9.3k times · Source

I am trying to implement a while loop using promises.

The method outlined here seems to work. http://blog.victorquinn.com/javascript-promise-while-loop it uses a function like this

var Promise = require('bluebird');

var promiseWhile = function(condition, action) {
    var resolver = Promise.defer();

    var loop = function() {
        if (!condition()) return resolver.resolve();
        return Promise.cast(action())
            .then(loop)
            .catch(resolver.reject);
    };

    process.nextTick(loop);

    return resolver.promise;
};

This seems to use anti-patterns and deprecated methods like cast and defer.

Does anyone know a better or more modern way to accomplish this?

Thanks

Answer

Bergi picture Bergi · Apr 1, 2015

cast can be translated to resolve. defer should indeed not be used.

You'd create your loop only by chaining and nesting then invocations onto an initial Promise.resolve(undefined).

function promiseWhile(predicate, action, value) {
    return Promise.resolve(value).then(predicate).then(function(condition) {
        if (condition)
            return promiseWhile(predicate, action, action());
    });
}

Here, both predicate and action may return promises. For similar implementations also have a look at Correct way to write loops for promise. Closer to your original function would be

function promiseWhile(predicate, action) {
    function loop() {
        if (!predicate()) return;
        return Promise.resolve(action()).then(loop);
    }
    return Promise.resolve().then(loop);
}