I'm using the Q module for Node.js in attempts to avoid the "pyramid of doom" in scenarios where I have many steps. For example:
function doTask(task, callback)
{
Q.ncall(task.step1, task)
.then(function(result1){
return Q.ncall(task.step2, task);
})
.then(function(result2){
return Q.ncall(task.step3, task);
})
.fail(callback).end();
}
Essentially this seems to work; if an error is thrown by any of the task steps, it is passed to the callback (though I would be welcome to improvements, as I am new to node.js promises). However, I have a problem when I need to abort the task-chain early. For example, if result1 is successfully returned I might want to call the callback early and abort the rest, but my attempts to do so are failing...
function doTask(task, callback)
{
Q.ncall(task.step1, task)
.then(function(result1){
if(result1)
{// the rest of the task chain is unnecessary
console.log('aborting!');
callback(null, result1);
return null;
}
return Q.ncall(task.step2, task);
})
.then(function(result2){
console.log('doing step 3...');
return Q.ncall(task.step3, task);
})
.fail(callback).end();
}
In this example, I see both "aborting!" and "doing step 3..." printed.
I'm sure I'm merely misunderstanding some basic principles here, so would appreciate any help. Thanks!
Any errors that are thrown within the promise chain will cause the entire stack to be aborted early and control is given to the error-back path. (in this case, the fail() handler) When you detect a certain state which causes you to want to abort the promise chain, then just throw a very specific error, which you trap in the error-back and ignore (if you so choose)
I believe you only have to reject the promise to break out of the promise chain.
https://github.com/kriskowal/q/wiki/API-Reference#qrejectreason
also it seems like .end() has been changed to .done()
This is a case where you will need to branch, which does mean either nesting or creating a subroutine.
Or