Me cuesta entender la diferencia entre poner .catchANTES y DESPUÉS en una promesa anidada.
Alternativa 1:
test1Async(10).then((res) => {
return test2Async(22)
.then((res) => {
return test3Async(100);
}).catch((err) => {
throw "ERROR AFTER THEN";
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Alternativa 2:
test1Async(10).then((res) => {
return test2Async(22)
.catch((err) => {
throw "ERROR BEFORE THEN";
})
.then((res) => {
return test3Async(100);
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
El comportamiento de cada función es el siguiente, prueba1 falla si número es <0prueba2 falla si número es > 10y prueba3 falla si número no lo es 100. En este caso, test2 solo falla.
Intenté ejecutar y hacer que test2Async fallara, tanto ANTES como DESPUÉS se comporta de la misma manera y eso no está ejecutando el test3Async. ¿Alguien puede explicarme la principal diferencia entre colocar capturas en diferentes lugares?
En cada función, console.log('Running test X')para verificar si se ejecuta.
Esta pregunta surge debido al hilo anterior que publiqué ¿Cómo convertir la devolución de llamada anidada en una promesa? . Me imagino que es un problema diferente y vale la pena publicar otro tema.
fuente

Respuestas:
Entonces, básicamente estás preguntando cuál es la diferencia entre estos dos (dónde
pestá una promesa creada a partir de un código anterior):y
Existen diferencias cuando p resuelve o rechaza, pero si esas diferencias importan o no depende de lo que haga el código dentro de los controladores
.then()o.catch().Qué sucede cuando
presuelve:En el primer esquema, cuando se
presuelve,.then()se llama al controlador. Si ese.then()controlador devuelve un valor u otra promesa que finalmente se resuelve,.catch()se omite el controlador. Pero, si el.then()manejador arroja o devuelve una promesa que finalmente se rechaza, entonces el.catch()manejador ejecutará tanto un rechazo en la promesa originalpcomo un error que ocurra en el.then()manejador.En el segundo esquema, cuando se
presuelve,.then()se llama al controlador. Si ese.then()manejador lanza o devuelve una promesa que eventualmente rechaza, entonces el.catch()manejador no puede captar eso porque está antes que él en la cadena.Entonces, esa es la diferencia n. ° 1. Si el
.catch()controlador es DESPUÉS, también puede detectar errores dentro del.then()controlador.Que pasa cuando
prechaza:Ahora, en el primer esquema, si la promesa se
prechaza,.then()se omite el.catch()controlador y se llamará al controlador como era de esperar. Lo que haces en el.catch()controlador determina qué se devuelve como resultado final. Si solo devuelve un valor del.catch()controlador o devuelve una promesa que finalmente se resuelve, entonces la cadena de promesa cambia al estado resuelto porque "manejó" el error y regresó normalmente. Si arroja o devuelve una promesa rechazada en el.catch()controlador, la promesa devuelta permanece rechazada.En el segundo esquema, si la promesa se
prechaza,.catch()se llama al controlador. Si devuelve un valor normal o una promesa que finalmente se resuelve desde el.catch()controlador (por lo tanto, "maneja" el error), entonces la cadena de promesa cambia al estado resuelto y se llamará al.then()controlador posterior.catch().Entonces esa es la diferencia # 2. Si el
.catch()controlador es ANTES, entonces puede manejar el error y permitir.then()que se siga llamando al controlador.Cuándo usar cuál:
Utilice el primer esquema si solo desea un
.catch()controlador que pueda detectar errores en la promesa originalpo en el.then()controlador y un rechazo depdebería omitir el.then()controlador.Utilice el segundo esquema si desea poder detectar errores en la promesa original
py tal vez (dependiendo de las condiciones), permitir que la cadena de promesa continúe como se resolvió, ejecutando así el.then()controlador.La otra opcion
Hay otra opción para usar ambas devoluciones de llamada a las que puede pasar
.then()como en:Esto garantiza que solo uno de
fn1ofn2será llamado. Si sepresuelve, entoncesfn1se llamará. Siprechaza, entoncesfn2será llamado. Ningún cambio de resultado enfn1nunca puede hacer quefn2te llamen o viceversa. Por lo tanto, si desea estar absolutamente seguro de que solo se llama a uno de sus dos controladores, independientemente de lo que suceda en los mismos controladores, puede usarp.then(fn1, fn2).fuente
.then()y.catch(), que respondes. Además, da algunos consejos sobre cuándo usar qué orden, donde creo que es apropiado mencionar una tercera opción, es decir, pasar el controlador de éxito y error a .then () . En ese caso, se llamará a un controlador como máximo.Promise.reject(new Error("F")).then(x => x).catch(e => {console.log(e); return [1]}).then(console.log)yPromise.resolve([2]).then(x => x).catch(e => [1]).then(console.log).then(this.setState({isModalOpen: false})). No está pasando una referencia de función a.then()para que el código en los parens se ejecute inmediatamente (antes de que se resuelva la promesa). Debería serlo.then(() => this.setState({isModalOpen: false})).La respuesta de jfriend00 es excelente, pero pensé que sería una buena idea agregar el código sincrónico análogo.
es similar al sincrónico:
Si
iMightThrow()no lanza,then()se llamará. Si lanza (o sithen()lanza él mismo), entonceshandleCatch()será llamado. Observe cómo elcatchbloque no tiene control sobre sithense llama o no .Por otra parte,
es similar al sincrónico:
En este caso, si
iMightThrow()no lanza,then()se ejecutará. Si arroja, entonces dependerá dehandleCatch()decidir sithen()se llama, porque si sehandleCatch()vuelve a lanzar,then()no se llamará, ya que la excepción se lanzará al llamador inmediatamente. SihandleCatch()puede manejar el problema con elegancia, entoncesthen()será llamado.fuente
then()en unfinally{...}then()enfinally{...}, ¿no forma incorrecta puede llamar incluso sihandleCatch()lanza? Tenga en cuenta que mi objetivo era mostrar código síncrono análoga, no es sugerir diferentes formas de manejo de excepciones