1

I'm fairly new to promises and have a problem wrapping my head around the Q.when() chain.

I want to execute my promises sequentially.

This is what I've got so far. It's running sequential but it's not resolving my URLs. parseUrls(urls) should return an array of all parseUrl(url) resolutions.

function parseUrl(url) {
    return function () {
        var deferred = Q.defer();

        // setTimeout as async placeholder
        setTimeout(function() {         
            var result = {url: url};
            deferred.resolve(result);
        }

        return deferred.promise;
    }
}

function parseUrls(urls) {
    var deferred = Q.defer();

    var chain = Q.when();
    urls.forEach(function (url) {
        chain = chain.then(parseUrl(url));
    });
    chain = chain.then(deferred.resolve);

    return deferred.promise;
}

getAllUrls()
    .then(parseUrls)
    .then(parseCards);
boop
  • 7,413
  • 13
  • 50
  • 94
  • You don't need to use deferreds at all. – SLaks Nov 18 '15 at 19:49
  • @SLaks I've edited my question. When your comment resulted from my example code not using async code, then this is fixed now. My bad. – boop Nov 18 '15 at 19:52
  • Sounds like a duplicate of [How to return accumulated returned Promise values as array to .then() following Array.prototype.reduce()?](http://stackoverflow.com/q/33688342/1048572). Is it? – Bergi Nov 18 '15 at 19:56

2 Answers2

2

For sequential execution, chain your promises with $q.all

function parseUrls(urls) {

    var chain = $q.when([]);

    for (var i=0; i<urls.length; i++) {
        (function (i, urls) {
            chain = chain.then ( function (result) {
                result.push(parseUrl(urls[i]));
                return $q.all(result);
            });
        })(i, urls);
    };

    return chain;
}

Be sure to put i and urls inside a closure.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
-1

Maybe I'm misunderstanding what you want to do, but it looks like you just need to simplify your parseUrls function a bit and use Q.all (docs). Q.all returns a new promise for the collected results from the array of promises you pass in:

function parseUrls(urls) {
    return Q.all(urls.map(function (url) {
        return parseUrl(url);
    }));
}
Ben
  • 10,056
  • 5
  • 41
  • 42