CppLearner
CppLearner

Reputation: 17040

Q.all returns the async function instead of the value I want to resolve

Here is my small demo script.

The idea is that at some point in my promise chain, I will call doAll which calls Q.all to process a batch of async operations. The result is then returned before I proceed to the next promise chain because that next method I will call might actually need the result from Q.all.

I kind of feel my code below isn't doing my end goal, but right now, doAll just resolves the function back instead of the value I really want to resolve. Q.all didn't even wait for Q.delay to do anything.

Output

vagrant@precise64:~$ node p.js
Starting step 1
the then after doAll
[ [Function: doAsync], [Function: doAsync] ]

Code

var Q = require('q');

function doAsync() {
    console.log('doing async');
    return Q.delay(3000).thenResolve('finished');
};

// A helper function that calls a batch of async operations
// In real code this could be a mix of async calls.
function doAll() {
    var deferred = Q.defer();
    Q.all([doAsync, doAsync])
     .then(function (results) {
        deferred.resolve(results);
      });
    return deferred.promise;
};

// In real app this function may have a chained
// of promises (step1 - 3)
//     step1()
//       .step2()
//       .step3()
//       .doAll()
//       .tearDown()
//       .done();
// But here we just imagine all these steps in
// a single function.
function starter() {
    console.log("Starting step 1");
    return Q.delay(1000);
}

// Idea:
// We start with 1 or more steps, then we
// call doAll and wait for all of them to complete
// before return the batch result.
starter()
  .then(function () {
    doAll()
    .then(function(results) {
        console.log("the then after doAll");
        console.log(results);
    })
});

The code above using Q.delay is inspired by this demo code: http://jsfiddle.net/jfromaniello/FRRxM/3/light/

Upvotes: 0

Views: 4995

Answers (1)

Vadim
Vadim

Reputation: 8789

You get array of functions in the results because Q.all should receive as argument array of promises and not array of factory functions creating that promises. Documentation you can find here.

Also, you don't need to create another deferred object to fetch results from Q.all and pass it to next async function:

JavaScript

function doAsync1() {
    console.log('Async 1');
    return Q.delay(3000).thenResolve('finished1');
};

function doAsync2() {
    console.log('Async 2');
    return Q.delay(3000).thenResolve('finished2');
};

function starter() {
    console.log("Starter");
    return Q.delay(1000);
}

function doAll() {
    return Q.all([doAsync2(), doAsync2()]);
}

starter().
    then(doAsync1).
    then(doAll).
    then(function(results) {
        console.log("after doAll");
        console.log(results);
    });

Result

Starter
Async 1
Async 2
Async 2
after doAll
["finished2", "finished2"] 

Example: http://jsfiddle.net/St7YS/1/

Upvotes: 4

Related Questions