javascript - then - Bluebird promete y captura ramificación
try catch promise js (1)
Me pregunto si hay una forma en que Bluebird prometa .catch
un error lanzado y luego procesar algunas acciones específicas sin ramificación (promesa anidada).
Digamos que tengo
doSomethingAsync()
.then(function (result) {
if (!result)
throw new CustomError(''Blah Blah'');
if (result == 0)
throw new CustomError2(''Blah Blah Blah'');
return result;
})
.then(function (result) {
console.log(''Success, great!'');
})
.catch(CustomError, function (error) {
// Oh CustomError!
return saveSomethingAsync();
})
.then(function (saved) {
// Should only be executed if an CustomError has been thrown
console.log("Let''s try again");
return doSomethingAsync();
})
.catch(CustomError2, function (error) {
// Oh CustomError2!
})
.delay(15000) // Don''t try again now !
.then(function () {
// Should only be executed if an CustomError2 has been thrown
console.log("Let''s try again after some long delay");
return doSomethingAsync();
})
.catch(function (error) {
// Should catch all random errors of the chain
})
Cuando ejecuto este código, obtengo varios comportamientos:
- Si no se produce ningún error, obtengo "¡Éxito, genial!" y comienza de nuevo con "Probemos de nuevo después de un largo retraso"
- Si CustomError lanza, obtengo "Probemos de nuevo"
- Si CustomError2 arroja, obtengo "Probemos de nuevo después de un largo retraso"
No puedo entender qué está pasando con este flujo. Sería genial escribir algo como esto en lugar de anidar el código específico de los errores en las nuevas cadenas de promesas.
.catch
un error lanzado y luego procesar algunas acciones específicas sin ramificar
No. Porque eso es una bifurcación. Anidar es totalmente natural aquí. Incluso podrías pensar en esto usando la metáfora de try-catch
sincrónica y sería lo mismo.
No puedo entender qué está pasando con este flujo.
- Si no se produce ningún error, obtengo "¡Correcto, genial!" y comienza de nuevo con "Probemos de nuevo después de un largo retraso"
Hm, eso es extraño, porque el "Probemos de nuevo" (sin demora) está encadenado antes de eso. Eventualmente deberías obtener ambos registros. Su cadena se procesa secuencialmente:
doSomethingAsync() // returns a result
then return result // first callback: continues with it
then console.log(''Success, great!'') // next callback: logs something
catch // is ignored because no rejection
then console.log("Let''s try again"); // next callback: logs something
return doSomethingAsync(); // and returns a result
catch // that result, not being a rejection, is ignored here
delay // fulfillment is delayed
then console.log("Let''s try again after some long delay"); // next callback again logs
return doSomethingAsync(); // and returns a result
catch // is ignored again
- Si se lanza un CustomError, obtengo "Let''s try again"
Sí, porque saveSomethingAsync();
, se cumple el resultado de la promesa anterior, por lo que se .then()
la siguiente .then()
devolución de llamada en la cadena.
- Si se lanza un CustomError2, aparece "Probemos de nuevo después de un largo retraso"
Sí, porque el error borró todo el camino hasta .catch(CustomError2, …)
donde finalmente se manejó. En su camino, no se ejecutaron callbacks. Después de que se manejó el error , se cumple la promesa, y el siguiente .then()
en la cadena llama a su devolución de llamada.
Creo que lo que realmente quieres aquí es
doSomethingAsync()
.then(function(result) {
if (!result)
// CustomError(''Blah Blah'');
// Oh CustomError!
return saveSomethingAsync();
.then(function(saved) {
console.log("Let''s try again");
return doSomethingAsync();
});
else if (result == 0)
// CustomError2(''Blah Blah Blah'');
// Oh CustomError2!
return Promise.delay(15000) // Don''t try again now !
.then(function() {
console.log("Let''s try again after some long delay");
return doSomethingAsync();
})
else
console.log(''Success, great!'');
// return undefined implied
}).catch(function (error) {
// does catch all random errors of the chain
// thrown by any of the doSomethingAsync() or of the saveSomethingAsync
})