-
-
Save yiminghe/1723027 to your computer and use it in GitHub Desktop.
var d = Q.defer(), | |
ret = [], | |
p = d.promise; | |
var p2 = p.then( | |
function (v) { | |
ret.push("e1 :" + v); | |
throw "e1"; | |
}, | |
function (r) { | |
ret.push("e2 :" + r); | |
return "e2"; | |
}); | |
var p3 = p2.then( | |
function (v) { | |
ret.push("e3 :" + v); | |
throw "e3"; | |
}, | |
function (r) { | |
ret.push("e4 :" + r); | |
return "e4"; | |
}); | |
var p4 = p3.then(function (v) { | |
ret.push("e5 :" + v); | |
throw "e5"; | |
}, function (r) { | |
ret.push("e6 :" + r); | |
return "e6"; | |
}); | |
setTimeout(function () { | |
d.resolve(1); | |
}, 100); | |
setTimeout(function () { | |
alert(ret.join("\n")); | |
}, 200); |
Why would you expect e6: e4
?
Consider:
var p4 = p3.then(function (v) {
ret.push("e5 :" + v);
throw "e5";
}, function (r) {
ret.push("e6 :" + r);
return "e6";
});
p3
is a fulfilled promise, since the error handler does return "e4"
instead of re-throwing. This signals successful recovery, just like not rethrowing in a catch
block.
Thus, the fulfillment handler for p3
will be run with the value p3
is fulfilled with, viz. "e4"
. So "e5 :e4"
is as expected.
To get your expected behavior, just re-throw instead of recovering: change line #22 to throw "e4"
instead of return "e4"
.
To be further illustrative, your code is the equivalent of:
function p() {
return 1;
}
function p2() {
var v;
try {
v = p();
} catch (r) {
ret.push("e2 :" + r);
return "e2";
}
ret.push("e1 :" + v);
throw "e1";
}
function p3() {
var v;
try {
v = p2();
} catch (r) {
ret.push("e4: " + r);
return "e4";
}
ret.push("e3 :" + v);
throw "e3";
}
function p4() {
var v;
try {
v = p3();
} catch (r) {
ret.push("e6 :" + r);
return "e6";
}
ret.push("e5 :" + v);
throw "e5";
}
p4();
As you can see, the code path that gets followed is:
p()
executes without errors; `"e1 :1"p2()
then throws"e1"
- So
p3
'scatch
clause gets entered:"e4: e1"
- That
catch
clause returns"e4"
, i.e.p3()
returns"e4"
- So
p4
'scatch
clause is never entered:"e5 :e4"
.
@DomenicDenicola :
Thank you , i misunderstood the error callback of promise at first, i thought it is just used for error propagation and notification.
Now i see it can also be used for recovery :)
@yiminghe happy to help! :)
KISSY's result is what i want: