Ejemplo:
let a = Promise.resolve("123") .then(val => { console.log(a); return 100; }) .then(val => { console.log(val); console.log(a); }) .finally(() => { console.log(a); });Producción:
Promise { <pending> } 100 Promise { <pending> } Promise { <pending> }¿Por qué una promesa resuelta aún en estado pendiente?
Entonces, a contiene el resultado de ejecutar todo esto:
let a = Promise.resolve(...).then(...).then(...).finally(...); Cada paso de esa fase crea a nueva promesa y contiene la última de la cadena (la última promesa es la que .finally() ). Cada vez que inicia a , está registrando la promesa final y aún no se ha resuelto hasta que se completa la cadena.
Tenga en cuenta que todos estos .then() y .finally() se ejecutan inmediatamente y cada uno devuelve una nueva promesa. Cuando se ejecutan, registran las devoluciones de llamada que se les pasan de manera que esas devoluciones de llamada se puedan llamar más tarde cuando la promesa con la que están asociados se resuelva o rechace. A pesar de que la primera promesa se resuelve de inmediato, todavía no ejecuta sus controladores .then() hasta después de que se ejecuta toda esta cadena de .then().then().finally() y se crean todas las promesas en esa cadena y todos los manejadores especificados en esa cadena están registrados. Por lo tanto, a contiene la cuarta promesa que .finally() , no la promesa que crea Promise.resolve() y esa cuarta promesa no se resuelve hasta que todos los controladores de su cadena hayan terminado de ejecutarse. Dado que está realizando el registro de todos esos controladores, es por eso que la última promesa en la cadena todavía se muestra como pending en todos los lugares donde la está registrando.
Si haces las cosas de manera diferente como esta:
let d = Promise.resolve("123"); d.then(val => { console.log(d); return 100; }).then(val => { console.log(val); console.log(d); }).finally(() => { console.log(d); });Entonces, verás esto:
Promise { '123' } 100 Promise { '123' } Promise { '123' } Porque ahora d representa la primera promesa de la cadena, no la promesa final de la cadena, por lo que se resuelve cuando se ejecutan todos los demás controladores.
Entonces, probablemente la parte operativa aquí de la que no estabas al tanto es que cada .then() , .catch() o .finally() devuelve una nueva promesa que está enganchada a la cadena frente a ella. Su console.log(a) original estaba monitoreando solo la última promesa en la cadena, no la primera promesa en la cadena o no la promesa actual en la cadena.