Estoy tratando de entender algo sobre el siguiente comportamiento de las promesas.
Cuando push una promesa a la matriz de promises , se ejecuta console.log . Creo que esto se debe a que a medida que push , en realidad ejecuto las promesas.
Pero luego, cuando intento hacer Promise.all , no veo que se impriman los mismos mensajes de console.log , es solo silencio. Puedo ver los valores devueltos de cada resolve si los desstructuro desde Promise.all y console.log , pero, de nuevo, no veo los mensajes de console.log (como Printed for promise A during push ).
¿Por qué está pasando esto?
import * as React from "react"; const promiseA = async ({}) => { return await new Promise((resolve) => { console.log("Printed for promise A during push"); resolve("promise a resolved"); }); }; const promiseB = async ({}) => { return await new Promise((resolve) => { console.log("Printed for promise B during push"); resolve("promise b resolved"); }); }; const Component = React.memo(() => { React.useEffect(() => { init(); }, []); const init = React.useCallback(async () => { let promises = []; promises.push(promiseA({})); // 'Printed for promise A during push' promises.push(promiseB({})); // 'Printed for promise B during push' await Promise.all(promises); // silence, nothing is printed /* // And if I do the following, I see the strings in `resolve`: const [responseA, responseB] = await Promise.all(promises); console.log("responseA", responseA); // responseA promise a resolved console.log("responseB", responseB); // responseB promise a resolved */ }, []); return <div />; }); export default Component;Las promesas no se pueden "ejecutar". Las promesas no describen acciones , describen los resultados de algunas acciones .
La función que pasa al constructor Promise se llama inmediatamente cuando se llama al constructor. Su trabajo es iniciar las acciones cuyo resultado representa la promesa. Eso significa que las acciones se inician cuando se crea la promesa.
new Promise((resolve) => { console.log("Printed during promise creation"); resolve("resolved"); });...es lo mismo que escribir...
console.log("Printed at the same time, but from outside the Promise callback"); new Promise((resolve) => { resolve("resolved"); }); Entonces, en su código, no es push la creación de esas promesas. Eres tú llamando a esas funciones creadoras de promesas.
promises.push( promiseA({}) ); // ^^^^--- calling function `promiseA` Lo que hizo que sus funciones fueran async puede ser otra fuente de confusión. Reescribamos su código de una manera un poco más clara:
//This used to be named `promiseA` const createPromiseA = () => { console.log("Called createPromiseA, about to create promiseA") return new Promise((resolve) => { console.log("Promise A created"); resolve("Promise A resolved"); }); }; //This used to be named `promiseB` const createPromiseB = () => { console.log("Called createPromiseB, about to create promiseB") return new Promise((resolve) => { console.log("Promise B created"); resolve("Promise B resolved"); }); }; let promises = []; let promiseA = createPromiseA(); //Called createPromiseA, about to create promiseA | Created promiseA let promiseB = createPromiseB(); //Called createPromiseB, about to create promiseB | Created promiseB //All the following will just move those promises around, no logs. promises.push(promiseA); promises.push(promiseB); //Neither will this log let results = await Promise.all(promises); //Logs the results as expected console.log(results) //["Promise A resolved", "Promise B resolved"]Parte de la confusión aquí es su nombre.
promiseA y promiseB no son promesas en su código, son funciones que devuelven una Promise .
Llamas a las funciones promiseA y promiseB y agregas los valores devueltos a la matriz.
Usar el valor de retorno de una función no volverá a llamar a la función. Los objetos de promesa devueltos se pueden usar para esperar a que se complete el código en las funciones. En este caso, no son asíncronos, por lo que se resolverán/completarán de inmediato.
Promise.all devuelve una nueva promesa que se resuelve cuando se resuelven todas las promesas de la matriz. En este caso, eso es de nuevo inmediatamente.
Pero no confunda la función llamada promise con el valor de retorno que en realidad es una Promise