Estoy tratando de comprender completamente los conceptos de asíncrono y promesas durante más de un año, pero todavía no puedo comprender todo al respecto.
La mayoría de los documentos de Promises tratan sobre 'no bloquear' y los códigos de ejemplo simulan solicitudes largas con un setTimeout de esta manera:
console.log('foo1'); let promiseA = new Promise(resolv => { setTimeout(() => resolv('finished'), 1000); }) promiseA.then(answer => { console.log(answer); }); console.log('foo2');
que cede a
"foo1" "foo2" "finished"
¿Pero no es esto mezclar dos conceptos diferentes a la vez? Según tengo entendido, las funciones setTimeout son funciones de navegador/tiempo de ejecución, setTimeout activa con precisión un contador interno en el subproceso del navegador , su función de devolución de llamada se vuelve a agregar al motor de JavaScript al final del tiempo de espera a través de la cola de macrotareas, lo que permite su js a continuación la llamada a la función para ejecutar todavía.
Pero, ¿qué pasa con los ejemplos en los que no se usa setTimeout? Considera esto:
let promiseA = new Promise(resolv => { uselesscounter = 0; for(let i = 0; i < 1000000000; i++) { uselesscounter+= 1; } resolv('finished'); }) promiseA.then(answer => { console.log(answer); }) console.log('foo2')
Desde el ejemplo superior, podríamos pensar que vamos a tener "foo1", "foo2", luego el ciclo tomará tiempo y tendríamos el "terminado" un par de segundos más tarde. No es lo que está pasando. Como el código ejecutor se ejecuta directamente (y no utiliza ninguna API de navegador) , está bloqueando el "foo2" debajo, a pesar de que al final la devolución de llamada de resolución se agrega a la cola de microtareas y se muestra después de "foo2".
Entonces, ¿tiene sentido una devolución de llamada como esa, que no usa las funciones de API del navegador?
Las promesas son útiles para usar cuando se esperan algunos datos o una señal de algún tipo desde fuera del código en sí, como llamadas a API y otras cosas.
Si su código es completamente independiente, no habrá ganancias de rendimiento al usar promesas.
En su segundo ejemplo, el código se ejecuta como se esperaba, porque las promesas no se ejecutan "más tarde". En una promesa, el código seguirá ejecutándose hasta encontrar una operación asincrónica que no se ejecuta en el contexto actual (hilo, trabajador, etc.), cuando eso suceda, no se bloqueará mientras espera el resultado, sino que ejecutará el líneas que siguen a la promesa hasta que se solicite el resultado de la promesa (usando esperar por ejemplo), y cuando eso suceda, su tiempo de ejecución devolverá el resultado de la promesa si está disponible, o bloqueará su programa hasta que haya un resultado disponible.
En su caso, los contenidos de la promesa son todos síncronos y, por lo tanto, bloquean.