JBone JBone - 2 months ago 11
Javascript Question

in chained promises, if first promise require to not to execute rest of the promises, how

I have 4 methods that each return a Promise, and I have them in chain structure. But not I have a condition in very first Promise that can be satisfied, so in this case I need/should not execute remaining Promises in chain. How can I do this?

here are the 4 tasks that are being accomplished

task 1)see if the data exists in Mongo, if not

task 2) call the SOAP service

task 3) using the result from SOAP, manipulate data

task 4) put this document in Mongo

This works fine, but when task 1 has the data, then I should not process next 3 Promises (tasks 2, 3, 4).

Here is my current Code

checkMongoForData(req, res)
.then(function (result) {
return makeTheSOAPcall(req, res, result)
.then(function (result) {
return fillTheReasonDescriptions(req, res, result);
})
.then(function (result) {
return upsertTheRespDocInMongo(req, res, result);
})
.then(function (result) {
res.status(200);
res.send({result: 'success', status: 200});
})
.catch(function (reject) {
res.status(reject.status);
res.send({result: reject.description, status: reject.status});
});


// my functions defined something like this

function checkMongoForData(req, res) {
return new Promise(function (resolve, reject) {
// TODO : the logic goes here
/// check to see for the data. If not there then continue
// if there is data, no need to do remaining tasks
});
}


How do I achieve this? Thanks.

Answer

In general, there are multiple ways to solve this problem.

One of them is by:

  • Using an additional catch() after your "four tasks chain"
  • "rejecting" (but not as an "error") the getDataFromMongo method in case of existing data (with a "dummy" error that we can actually check later)
  • "duck-typing" the rejection cause of the chain itself

It's not the best one, but it won't break nor significantly change your existing chain of promises (if you are willing to change your chain, you should most likely go with this answer by T.J. Crowder):

// This can be anything, as long as it's "unique"
var dummyError = "has no data";

function checkMongoForData(req, res) {
    return new Promise(function (resolve, reject) {
        // TODO: Replace with your logic
        var hasData = false;
        var data = "";

        if (hasData) {
            resolve(data);
        } else {
            reject(dummyError);
        }
    });
}

checkMongoForData(req, res)
    .then(function (result) {
        return makeTheSOAPcall(req, res, result)
    })
    .then(function (result) {
        return fillTheReasonDescriptions(req, res, result);
    })
    .then(function (result) {
        return upsertTheRespDocInMongo(req, res, result);
    })
    .catch(function (error) {
        if (error === dummyError) {
            return;
        }

        // This line "re-throws"/"re-rejects" the error object
        return Promise.reject(error);
    })
    .then(function (result) {
        res.status(200);
        res.send({result: 'success', status: 200});
    })
    .catch(function (reject) {
        res.status(reject.status);
        res.send({result: reject.description, status: reject.status});
    });