-
-
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
'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! :)
expected:
e1:1
e4:e1
e6:e4
actual result:
e1:1
e4:e1
e5:e4