Raj
Raj

Reputation: 699

Multiple promises in Node js

I am new to nodejs and struggling to find the issue with the below piece of code.

All i am trying to achieve is, calling few methods one after other and if all the calls are successful, then return success else throw an error if any of the method fails.

Issue i have is, before all the method gets executed, the main method terminates even though the promises are yet to be fullfilled.

Main method

processRequest(neworder).then(function (done) {
    console.log('Successfully processed the order' + done);
    res.sendStatus(200);
}).fail(function (error) {
    res.status(404).send(error);
})

Other method calls

module.exports.processRequest = function (Order) {
    var deferred = Q.defer();

    findX(Order)
        .then(findYBasedOnPrevOutput)
        .then(findZBasedOnPrevOutput)
        .then(deferred.resolve())
        .fail(function (err) {
            console.log('Failed to process request' + err);
            deferred.reject(err);
        });

    return deferred.promise;
}


var findX = function (order) {
    var deferred = Q.defer()

    db.list(order, function (address) {
        console.log('Query success');
        if (address == null)
            deferred.reject('Error');
        else {
            deferred.resolve(address);
        }
    })

    return deferred.promise;
};

Issue that i am having is, i see in the console the success just after the findX method gets called. I expected the success msg after findZ method.

Can you please help me in finding the issue with the above code, appreciate your input/suggestions in this regard

For simplicity, i didn't share the other modules here, but they are very similar to findX

Upvotes: 1

Views: 2389

Answers (1)

jfriend00
jfriend00

Reputation: 707158

I'd suggest you just use the promise you already have rather than creating a new one as both more efficient and to avoid a promise anti-pattern:

module.exports.processRequest = function (Order) {
  return findX(Order)
    .then(findYBasedOnPrevOutput)
    .then(findZBasedOnPrevOutput)
    .fail(function (err) {
      // log the error, then throw it again so it is returned as a rejected promise
      console.log('Failed to process request' + err);
      throw(err);
    });
}

And, I'd suggest changing findX to use Q's ability to turn a standard async call into one that returns a promise like this:

var findX = function(order) {
  return Q.nfcall(db.list.bind(db), order);
};

Or, combine the two like this:

module.exports.processRequest = function (Order) {
  return Q.nfcall(db.list.bind(db), Order)
    .then(findYBasedOnPrevOutput)
    .then(findZBasedOnPrevOutput)
    .fail(function (err) {
      // log the error, the throw it again so it is returned as a rejected promise
      console.log('Failed to process request' + err);
      throw(err);
    });
}

Upvotes: 1

Related Questions