es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

JS – ejecución del bucle de eventos con 2 promesas que se intersectan

Estaba tratando de entender qué sucede con el bucle de eventos en el navegador cuando hay 2 Promesas. Aquí proporciono mi código de prueba y mi comprensión a continuación:

const promiseA = new Promise(resolve => {
    resolve()
}).then(function() {
    console.log('promiseA - 1')
}).then(function() {
    console.log('promiseA - 2')
}).then(function() {
    console.log('promiseA - 3')
})

const promiseB = new Promise(resolve => {
    resolve()
}).then(function() {
    console.log('promiseB - 1')
    return
}).then(function() {
    console.log('promiseB - 2')
    return
}).then(function() {
    console.log('promiseB - 3')
    return
})

// promiseA - 1
// promiseB - 1
// promiseA - 2
// promiseB - 2
// promiseA - 3
// promiseB - 3

Mi comprensión:

Cuando se resuelve promiseA, el console.log('promiseA - 1') se agregará a la cola de tareas; luego, se resuelve promiseB, y console.log('promiseB - 1') se agregará a la cola de tareas.

En este punto, ya que la pila de llamadas está vacía, se ejecuta console.log('promiseA - 1'), y el siguiente manejador console.log('promiseA - 2') se agregará a la cola de tareas, y así sucesivamente …

Hasta el momento, el resultado es como esperaba. (Por favor, corríjame si estoy equivocado, gracias).

Luego quiero ver cuál es la diferencia entre devolver un valor puro (por ejemplo, undefined, en mi ejemplo) y devolver un valor basado en Promesa (es decir, Promise.resolve(value)) en el manejador then.

Código:

const promiseA = new Promise(resolve => {
    resolve()
}).then(function() {
    console.log('promiseA - 1')
}).then(function() {
    console.log('promiseA - 2')
}).then(function() {
    console.log('promiseA - 3')
}).then(function() {
    console.log('promiseA - 4')
}).then(function() {
    console.log('promiseA - 5')
}).then(function() {
    console.log('promiseA - 6')
}).then(function() {
    console.log('promiseA - 7')
}).then(function() {
    console.log('promiseA - 8')
}).then(function() {
    console.log('promiseA - 9')
})

const promiseB = new Promise(resolve => {
    resolve(Promise.resolve())
}).then(function() {
    console.log('Promise.resolve() - 1')
    return Promise.resolve()
}).then(function() {
    console.log('Promise.resolve() - 2')
    return Promise.resolve()
        .then(() => console.log('then'))
}).then(function() {
    console.log('Promise.resolve() - 3')
    return Promise.resolve()
})

// promiseA - 1
// promiseA - 2
// promiseA - 3
// Promise.resolve() - 1
// promiseA - 4
// promiseA - 5
// promiseA - 6
// Promise.resolve() - 2
// promiseA - 7
// then
// promiseA - 8
// promiseA - 9
// Promise.resolve() - 3

Aquí viene mi pregunta, ¿alguien puede explicarme qué sucede aquí? Parece haber 3 rondas de ejecución de bucles de eventos cuando se devuelve Promise.resolve() en el manejador, ¿por qué?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Cuando se devuelve Promise.resolve() en el controlador, se hace que la función then siguiente se ejecute de forma asíncrona después de que la actual se complete. En otras palabras, la promesa devuelta se resuelve inmediatamente, pero su función then se agrega al final de la cola de tareas y se ejecuta una vez que la pila de llamadas está vacía.

    En el caso de promiseB, cuando se resuelve, la primera función then console.log('Promise.resolve() - 1') se ejecuta de manera síncrona y se empuja a la cola de tareas. La segunda función then console.log('Promise.resolve() - 2') también se empuja a la cola de tareas ya que devuelve una promesa resuelta. Sin embargo, la tercera función then console.log('Promise.resolve() - 3') no se empuja inmediatamente a la cola de tareas porque devuelve una promesa resuelta con otra función then dentro de ella.

    Después de la ejecución síncrona de console.log('Promise.resolve() - 1'), el ciclo de eventos recupera la siguiente tarea de la cola, que es la función then que se devolvió de la segunda llamada a then. Esta función then contiene una función then anidada que se empuja al final de la cola de tareas. Por lo tanto, la declaración console.log('then') dentro de la función then anidada es la siguiente tarea que se ejecutará después de que se complete la función then actual. Una vez completada esta tarea, el ciclo de eventose recupera la siguiente tarea de la cola, que es la tercera función then que se devolvió de la segunda llamada a then.

    Este patrón se repite para cada promesa resuelta que devuelve otra promesa con una función then dentro. Por lo tanto, hay en realidad cuatro rondas de ciclo de eventos que se ejecutan en este ejemplo, con el siguiente orden de ejecución:

    1. promiseA - 1
    2. promiseA - 2
    3. promiseA - 3
    4. Promise.resolve() - 1
    5. promiseA - 4
    6. promiseA - 5
    7. promiseA - 6
    8. Promise.resolve() - 2
    9. then
    10. promiseA - 7
    11. promiseA - 8
    12. promiseA - 9
    13. Promise.resolve() - 3

Comments are closed.