Sé que una función de devolución de llamada dentro setTimeout() esperará hasta que expire el temporizador adjunto y se inserte en una cola de devolución de llamada. Por otro lado, una promesa, una vez cumplida o rechazada, recibe su devolución de llamada en una cola de microtareas, que tiene mayor prioridad.
Mi pregunta es cuál es más rápido una vez: un setTimeout dentro de una promesa o un simple setTimeout . Si el primero ya no se coloca en la cola de microtareas, ¿por qué solo setTimeout se ejecuta primero y no al revés?
setTimeout(() => { console.log('timeout'); }, 1000); let promise = new Promise(function(resolve, reject) { // This is run automatically, let's run resolve after 1 second setTimeout(() => resolve('promise!'), 1000); }); promise.then( (result) => console.log(result), (err) => console.log(error) ); // output: timeout -> promise || and not || promise -> timeoutAhora supongamos que olvido el retraso de 1 segundo, ahora la promesa siempre aparecerá primero ya que la devolución de llamada programada dentro de la cola de microtareas tiene mayor prioridad
setTimeout(() => { console.log('timeout'); }, 0); let promise = new Promise(function(resolve, reject) { // This is run automatically, let's run resolve after 1 second // setTimeout(() => resolve('promise!'), 1000); resolve(''); }); promise.then(() => { console.log('promise'); });setTimeout se implementa de una manera que debe ejecutarse después de un retraso mínimo dado, y una vez que el hilo del navegador está libre para ejecutarlo. entonces, por ejemplo, si especifica un valor de 0 para el parámetro de retraso y cree que se ejecutará "inmediatamente", no lo hará. se ejecutará, con mayor precisión, en el próximo ciclo de eventos (que es parte del ciclo de eventos, modelo de concurrencia que es responsable de ejecutar el código).
Tomemos el ejemplo para un valor de retardo de 0.
setTimeout(() => { console.log('timeout'); }, 0); let promise = new Promise(function(resolve, reject) { setTimeout(() => resolve('promise!'), 0); }); promise.then( (result) => console.log(result), (err) => console.log(error) ); setTimeout siempre registrará su resultado primero porque seguramente se ejecutará en el próximo ciclo de eventos.
El setTimeout en la promesa, por otro lado, tendrá 2 ciclos de eventos hasta que se ejecute el registro de la consola (uno para la resolución de la promesa y el otro para la devolución de llamada en la función setTimeout).
Lea el motivo de los retrasos más largos de lo especificado: https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
Más información sobre el bucle de eventos de JS: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop