He estado probando promesas en node.js en el siguiente programa:
const areallylongprocesspromise = new Promise((resolve, reject) => { let buff = 0; for (let i = 0; i < 1000000000; i++) { if ((i % 73829) === 0) buff++; } if (buff > 10) resolve(buff); else reject(buff); }); areallylongprocesspromise.then((resolved) => { console.log("Resolved: ", resolved); }) .catch((rejected) => { console.log("Rejected: ", rejected); }); console.log("Waiting for execution to finish up");La salida esperada es:
Waiting for execution to finish up Resolved: 13545Sin embargo, la primera declaración, "esperando... arriba" no se registra hasta que la promesa termina de ejecutarse, momento en el cual ambas declaraciones se registran simultáneamente. Soy nuevo en el concepto de promesas, así que no sé qué está pasando aquí. ¿Por qué la promesa retrasa la ejecución del resto del código? Cualquier ayuda sería apreciada.
El código dentro de la Promesa no se ejecuta cuando llama a .then , se ejecuta cuando define la Promesa en sí misma; intente registrar algo al comienzo de la función:
const areallylongprocesspromise = new Promise((resolve, reject) => { console.log('start'); ... });Dado que su código es síncrono, mantiene la ejecución del código por definición.
Eso sucede porque NodeJS y Javascript, a pesar de permitir llamadas asincrónicas de E/S, forman aplicaciones de un solo subproceso.
Significa que cuando la CPU está computando
for (let i = 0; i < 1000000000; i++) { if ((i % 73829) === 0) buff++; }No hace nada más.
Si usa, por ejemplo, setTimeout , funciona como se esperaba porque crea un temporizador asíncrono que funciona como una operación de E/S.
const areallylongprocesspromise = new Promise((resolve, reject) => { let buff = 0; for (let i = 0; i < 1000000000; i++) { if ((i % 73829) === 0) buff++; } setTimeout(()=> { if (buff > 10) resolve(buff); else reject(buff); }, 1000) }); areallylongprocesspromise.then((resolved) => { console.log("Resolved: ", resolved); }) .catch((rejected) => { console.log("Rejected: ", rejected); }); console.log("Waiting for execution to finish up");Este temporizador es inútil aquí, solo para mostrarle cómo funcionan las llamadas asincrónicas de E/S. Ese temporizador podría representar, por ejemplo, la lectura de un archivo, la conexión a una base de datos o la obtención de una imagen de Internet, todas son operaciones de E/S.
Esa es la magia de NodeJS, a pesar de ser de un solo subproceso, no bloquea el código para las operaciones de E/S.