Entonces, básicamente estás preguntando cuál es la diferencia entre estos dos (dónde p
está una promesa creada a partir de un código anterior):
return p.then(...).catch(...);
y
return p.catch(...).then(...);
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 p
resuelve:
En el primer esquema, cuando se p
resuelve, .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 original p
como un error que ocurra en el .then()
manejador.
En el segundo esquema, cuando se p
resuelve, .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 p
rechaza:
Ahora, en el primer esquema, si la promesa se p
rechaza, .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 p
rechaza, .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 original p
o en el .then()
controlador y un rechazo de p
debería omitir el .then()
controlador.
Utilice el segundo esquema si desea poder detectar errores en la promesa original p
y 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:
p.then(fn1, fn2)
Esto garantiza que solo uno de fn1
o fn2
será llamado. Si se p
resuelve, entonces fn1
se llamará. Si p
rechaza, entonces fn2
será llamado. Ningún cambio de resultado en fn1
nunca puede hacer que fn2
te 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 usar p.then(fn1, fn2)
.