-
-
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); |
KISSY's result is what i want:
var d = KISSY.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'scatchclause gets entered:"e4: e1" - That
catchclause returns"e4", i.e.p3()returns"e4" - So
p4'scatchclause is never entered:"e5 :e4".
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! :)
expected:
e1:1
e4:e1
e6:e4
actual result:
e1:1
e4:e1
e5:e4