I have the following code (http://jsfiddle.net/tj1eo86s/):
promise(1).then(function() {
console.log("OK1");
promise(2).then(function() {
console.log("OK2");
promise(3).then(function() {
console.log("OK3");
}, function() {
console.log("KO3");
});
}, function() {
console.log("KO2");
});
}, function() {
console.log("KO1");
});
If promise(2) is rejected, the output will be:
OK1
KO2
How can I obtain the same behavior while chaining the promises?
I tried with (http://jsfiddle.net/7goh0ds9/):
promise(1)
.then(function() {
console.log("OK1");
return promise(2);
}, function() {
console.log("KO1");
})
.then(function() {
console.log("OK2");
return promise(3);
}, function() {
console.log("KO2");
})
.then(function() {
console.log("OK3");
}, function() {
console.log("KO3");
});
But the output is:
OK1
KO2
OK3
Then I tried to throw an error in the error callbacks (http://jsfiddle.net/cyx6mohy/):
promise(1)
.then(function() {
console.log("OK1");
return promise(2);
}, function() {
console.log("KO1");
throw "KO1";
})
.then(function() {
console.log("OK2");
return promise(3);
}, function() {
console.log("KO2");
throw "KO2";
})
.then(function() {
console.log("OK3");
}, function() {
console.log("KO3");
throw "KO3";
});
But now I have:
OK1
KO2
KO3
I actually understand all those behaviors, but I have not been able to find a solution to handle errors as if promises were nested.
If your question is how to I generically make chaining handle errors the exact same way as arbitrary nesting, the answer is that you can't in a generic way. Chaining is a fundamentally different control structure than arbitrary nesting.
You could design a nesting that had fundamentally the same behavior as chaining. Or, if you had a specific error handling behavior from a nested structure that you wanted to emulate in a chained world, you "might" be able to use the appropriate error handling and control flow in a chained sequence to make that happen. Note, I say "might" because it depends entirely upon what the nested sequence was doing. You also might not be able to emulate it with pure chaining.
If your question is how do I make this sequence of chained promises generate this specific response when this specific promise in the chain rejects, then that might be possible, but it would be coded for your specific circumstance and desired outcome, not in some generic way.
Basically, there are reasons to use chaining and there are reasons to use nesting and reasons to use a combination of the two. Like you, I prefer chaining because the control flow and readability just seems simpler, so I always start out with that structure in mind, but there are definitely times in my code where I have to use nesting for some part of the operation (often because of branching decisions or certain types of required error handling).