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é?
davy.ai
Cuando se devuelve
Promise.resolve()
en el controlador, se hace que la funciónthen
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ónthen
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ónthen
console.log('Promise.resolve() - 1')
se ejecuta de manera síncrona y se empuja a la cola de tareas. La segunda funciónthen
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ónthen
console.log('Promise.resolve() - 3')
no se empuja inmediatamente a la cola de tareas porque devuelve una promesa resuelta con otra funciónthen
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ónthen
que se devolvió de la segunda llamada athen
. Esta funciónthen
contiene una funciónthen
anidada que se empuja al final de la cola de tareas. Por lo tanto, la declaraciónconsole.log('then')
dentro de la funciónthen
anidada es la siguiente tarea que se ejecutará después de que se complete la funciónthen
actual. Una vez completada esta tarea, el ciclo de eventose recupera la siguiente tarea de la cola, que es la tercera funciónthen
que se devolvió de la segunda llamada athen
.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:promiseA - 1
promiseA - 2
promiseA - 3
Promise.resolve() - 1
promiseA - 4
promiseA - 5
promiseA - 6
Promise.resolve() - 2
then
promiseA - 7
promiseA - 8
promiseA - 9
Promise.resolve() - 3