Let's suppose I have a Parse Cloud Code js function which I want to return a promise, like:
function doSomething(myObj, abortIfSaveFails) {
var dsPromise = new Parse.Promise();
myObj.set("name", "abc");
myObj.save().then(function(){
// location "A"
// great, it worked!
// don't want to actually do anything more in this block because
// we might want to do the same things even if save fails, and I
// don't want to repeat code
return Parse.Promise.as();
}, function(error){
// location "B"
// save failed, but we might want to keep going
if (abortIfSaveFails) {
// location "C": wish I could abort the whole promise chain here!
return Parse.Promise.error();
} else {
return Parse.Promise.as();
}
}).then(function(){
// location "D"
// at this point we're not sure if save succeeded but let's
// assume we don't need to know
return doSomethingCruciallyImportantAndReturnAPromise();
}, function(error){
// location "E":
// not sure if we got here because doSomethingCruciallyImportant...() errored or
// because myObj.save() errored.
// would be nice to abort the whole thing right now!
return Parse.Promise.error();
}).then(function(){
// location "F"
// at this point we know doSomethingElse... succeeded
return doSomethingUnimportantAndReturnAPromise();
}, function(error){
// location "G"
// not sure if we got here because doSomethingCruciallyImportant...() errored or
// because doSomethingUnimportant...() errored.
// If doSomethingCruciallyImportant...() succeeded but doSomethingUnimportant...()
// failed, I'd LIKE to do dsPromise.resolve()... but I can't resolve, because
// we might be in the process of aborting the function because myObj.save() rejected,
// or doSomethingCruciallyImportant rejected!
dsPromise.reject(); // might not be what I want to do!
}).then(function(){
// location "H"
// everything worked fine
dsPromise.resolve();
});
// location "I"
return dsPromise; // return the promise so `then` will wait
}
How can I refactor/rewrite this to better handle the situations at locations C, E, and G?
I realize I could dsPromise.reject() at C and E, but what would happen to the currently executing promise chain? Wouldn't it keep executing and move on to D, E, F, G etc.? Then couldn't I get to a place where I'm resolving dsPromise multiple times?