Reputation: 3
function sendOne() {
return new Promise(function(resolve, reject) {
QF.get("./data/1.json", {}, function(data) {
if (data.error === 0) {
resolve(data);
} else {
reject(data);
}
})
})
}
function sendTwo() {
return new Promise(function(resolve, reject) {
QF.get("./data/2.json", {}, function(data) {
if (data.error === 0) {
resolve(data);
} else {
reject(data);
}
})
})
}
function sendThree() {
return new Promise(function(resolve, reject) {
QF.get("./data/3.json", {}, function(data) {
if (data.error === 0) {
resolve(data);
} else {
reject(data);
}
})
})
}
var p1 = sendOne();
p1
.then(function(data) {
console.log("Succeeded for the first time");
return sendTwo();
}, function(data) {
console.log("Failed for the first time")
})
.then(function(data) {
console.log("Succeeded the second time");
return sendThree();
}, function(data) {
console.log("Failed the second time")
})
.then(function(data) {
console.log("Succeeded the third time");
}, function(data) {
console.log("Failed for the third time")
})
All three requests are wrong, and they should all output wrong results. Why is the second request successful? In my understanding, after the first request fails, it will be executed a second time, but it will also fail the second time. But the problem now is that it will succeed the second time
Upvotes: 0
Views: 67
Reputation: 21110
p1 // <- promise is rejected, go to next rejected handler
.then(function(data) { // |
// ... // |
}, function(data) { // <-----------------------+
console.log("Failed for the first time")
// no errors, successful undefined return value, go to next fulfilled handler
}) // |
.then(function(data) { // <--------------------+
console.log("Succeeded the second time");
return sendThree(); // <- promise is rejected, go to next rejected handler
}, function(data) { // |
// ... // |
}) // |
.then(function(data) { // |
// ... // |
}, function(data) { // <----------------------+
console.log("Failed for the third time")
})
If the reject handler doesn't throw an error or return rejected promise the result is considered a success, therefore the next .then()
will trigger the fulfilled handler. If you want to keep the reject handler chain going you have to re-throw the exception.
p1 // <- promise is rejected, go to next rejected handler
.then(function(data) { // |
// ... // |
}, function(data) { // <--------------------------+
console.log("Failed for the first time")
throw data; // <- causes the current promise to be rejected, go to next rejected handler
}) // |
.then(function(data) { // |
// ... // |
}, function(data) { // <--------------------------+
console.log("Failed the second time")
throw data; // <- causes the current promise to be rejected, go to next rejected handler
}) // |
.then(function(data) { // |
// ... // |
}, function(data) { // <--------------------------+
console.log("Failed for the third time")
})
Instead of throw data
you could also use return Promise.reject(data)
depending on your preference.
Alternatively you could place a single rejected handler at the end.
p1 // <- promise is rejected, go to the next reject handler
.then(function(data) { // |
console.log("Succeeded for the first time"); // |
return sendTwo(); // |
}) // |
.then(function(data) { // |
console.log("Succeeded the second time"); // |
return sendThree(); // |
}) // |
.then(function(data) { // |
console.log("Succeeded the third time"); // |
}, function(data) { // <------------------------------+
console.log("One, two or three failed.")
})
Upvotes: 1
Reputation: 521995
p1
.then(function(data) {
console.log("Succeeded for the first time");
return sendTwo();
}, function(data) {
console.log("Failed for the first time")
})
.then(function(data) {
console.log("Succeeded the second time");
return sendThree();
}, function(data) {
console.log("Failed the second time")
})
If p1
fails, the error handler console.log("Failed for the first time")
is being executed. This has caught the failure and prevented it from propagating. That's what error handlers/.catch
clauses are for in promise chains: to stop error propagation and allow the chain to continue. Which it then does with the next .then
, which prints console.log("Succeeded the second time")
, regardless of whether sendTwo()
was even called or not.
Upvotes: 2