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") })Las tres solicitudes son incorrectas y todas deberían generar resultados incorrectos. ¿Por qué la segunda solicitud tiene éxito? Según tengo entendido, después de que falla la primera solicitud, se ejecutará una segunda vez, pero también fallará la segunda vez. Pero el problema ahora es que tendrá éxito la segunda vez.
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") }) Si p1 falla, se ejecuta el controlador de errores console.log("Failed for the first time") . Esto ha detectado el error y ha impedido que se propague. Para eso están los manejadores de errores/cláusulas .catch en las cadenas de promesas: para detener la propagación de errores y permitir que la cadena continúe. Lo que luego hace con el siguiente .then , que imprime console.log("Succeeded the second time") , independientemente de si se llamó a sendTwo() o no.
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") }) Si el controlador de rechazo no arroja un error o no devuelve la promesa rechazada, el resultado se considera un éxito, por lo tanto, el siguiente .then() activará el controlador cumplido. Si desea mantener la cadena del controlador de rechazos, debe volver a lanzar la excepción.
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") }) En lugar de throw data , también podría usar return Promise.reject(data) según sus preferencias.
Alternativamente, puede colocar un solo controlador rechazado al final.
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.") })