Pensé que tenía una buena comprensión de Node and Promises, pero me encontré con este problema cuando estaba tratando de explicarle algo a un amigo mío.
Mi pregunta para ustedes, ¿cuál es el resultado esperado de este pequeño script?
const myPromise = new Promise((resolve, reject) => { console.log("inside promise") resolve("Lol!") }) for (let i=0; i<1000000; i++) {} // just want to be sure that the next line starts after the promise finishes execution myPromise.then(() => console.log("then!")) console.log("finished")Mi salida esperada:
inside promise finished Pensé que si la promesa finaliza la ejecución antes de myPromise.then(... se lea, ¿no debería aparecer nunca el registro?
Salida real:
inside promise finished then! Si emito la resolve("Lol!") , Aunque el resultado esperado coincide con el resultado real.
¿Alguien puede explicarme qué está pasando aquí?
¡Gracias!
Aquí está su ejemplo anotado:
console.log('Before myPromise is created'); const myPromise = new Promise((resolve, reject) => { // This is executed immediately when a new // Promise is created, so it will appear // BEFORE 'After myPromise is created'. console.log("Inside promise") // This passes the value "Lol!" to // the 'then' function. By itself it // does not console log anything. resolve("Lol!") }) console.log('After myPromise is created'); // This does nothing, code immediately // carries on executing. After >=100ms a function // doing nothing is called. setTimeout(() => {}, 100) // The 'then' is passed the argument of // `resolve()` (in this case "Lol!") myPromise.then(resolveArg => console.log(resolveArg)) // Second to last console log because // all .then() handlers are called asynchronously // once the main thread is idle (as the Promises/A+ // spec says, when the JS engine returns back to // "platform code"). Therefore "Lol!" will be the // last thing logged. console.log("Finished")La promesa de JS le brinda la opción de ejecutar el código de forma asincrónica. Entonces, le indica al motor JS que le gustaría realizar una acción una vez que finaliza otra acción. Dado que las acciones pueden tener éxito o no, las promesas pueden resolverse ( resolve ) o rechazarse ( reject ). Para manejar el éxito, use then para manejar el error, use catch , opcional después de ambos, puede usar finally .
Entonces, cuando declara una promesa, el motor JS sabe que no es algo que necesita ahora, sino más tarde. Comenzará la ejecución pero se relacionará con su resultado más adelante. Después de iniciar la acción de promesa, se ejecutará el resto de los comandos síncronos , en su caso, todos excepto el then . Una vez hecho esto, comprobará si tiene promesas que ya se hayan resuelto, en caso afirmativo, ejecutará las than correspondan.
El resolve() pone el then de la promesa en la cola de devolución de llamada. Más tarde, cuando la pila de llamadas esté vacía, el motor se encargará de eso. Lo mismo ocurriría con el reject() pero con catch .
Si desea mantener una sintaxis más limpia, le recomiendo verificar async-await.
* también tenga en cuenta que su setTimeout no le está dando nada. Si coloca console.log en él, también se mostrará solo después de 'finalizar'.
new Promise() maneja la operación que tiene que "esperar", luego devuelve el resultado al comando then () - esta es una operación asíncrona. Considere el siguiente ejemplo:
const myPromise = (val1, val2) => { return new Promise((resolve, reject) => { val1 > val2 ? setTimeout(() => resolve("LOL !!!"), 1500) : reject("\"val2\" is greater than \"val1\""); }); } // Then you call: myPromise(5, 1).then( // Processing results: function (result) { console.log("This is result: ", result); }, // Error handling from "reject()" function(error) { console.log("This is an error: ", error); } ) // error case: myPromise(1, 5).then( // Processing results: function (result) { console.log("This is result: ", result); }, // Error handling from "reject()" // the result in console.log will be first than in the case of resolve() function(error) { console.log("This is an error: ", error); } ) // Error handling with 'catch' block myPromise(1,5) .then((result) => console.log(result)) .catch((err) => console.log("This is error: ", err, "# with catch-block"))