Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

139
Visualizações
NodeJS Promise resuelve un comportamiento inesperado

Tengo el siguiente código, que no funciona como esperaba.

 const bar = () => console.log('bar') const baz = () => console.log('baz') const myPromise = new Promise((resolve, reject) => resolve('should be right after baz, before bar') ); const foo = () => { console.log('foo') setTimeout(bar, 0) myPromise.then(resolve => console.log(resolve)) baz() } foo() console.log('before bar')

El resultado:

 foo baz before bar should be right after baz, before bar bar

De acuerdo con lo que está escrito en https://nodejs.dev/ , la resolución de la promesa ocurrirá justo después de la función.

Las promesas que se resuelven antes de que finalice la función actual se ejecutarán inmediatamente después de la función actual.

Así que espero que 'debería ser justo después de baz, antes de bar' justo después del final de foo() , antes de console.log('before bar') . ¿Alguien puede explicar por qué no?

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Las devoluciones de llamadas pasadas a setTimeout se agregan a la cola de tareas, mientras que las devoluciones de llamadas relacionadas con el cumplimiento o el rechazo de promesas se agregan a la cola de microtareas.

Estas colas solo se procesan después de la ejecución síncrona de su secuencia de comandos, es decir, el código javascript que escribió.

Como resultado, 'before bar' se registra antes de que se invoque cualquier devolución de llamada asincrónica.

¿Cómo se ejecuta tu código?

  1. Comienza la ejecución del script.

  2. Se definen las funciones bar , baz y foo . También se llama al constructor de promesas, lo que conduce a la invocación de la función de resolve , resolviendo la promesa de forma síncrona.

  3. la funcion foo se llama

    1. 'foo' está registrado en la consola
    2. Se llama a setTimeout , la bar de programación se llamará de forma asíncrona. la bar se agregará en la cola de tareas
    3. then se llama al método en myPromise , programando el controlador de cumplimiento para que se invoque de forma asíncrona. Este controlador de cumplimiento se agrega en la cola de microtareas
    4. Se llama a la función baz , registrando 'baz' en la consola
  4. La función foo termina. Controle el regreso a la siguiente línea desde donde se llamó a foo

  5. Se ejecuta la última instrucción console.log , registrando 'before bar' en la consola

  6. Finaliza la ejecución del script

En este punto, la salida de la consola es como se muestra a continuación:

 foo baz before bar

y la cola de tareas contiene una tarea para ejecutar la función de bar , mientras que la cola de microtareas contiene una microtarea para ejecutar el controlador de cumplimiento de myPromise .

Una vez que finaliza la ejecución del script, se pueden procesar las colas de tareas y microtareas.

La cola de microtareas se procesa:

  • después de cada devolución de llamada siempre que la pila de llamadas esté vacía (esto es a lo que se refiere nodejs.dev)
  • después de cada tarea

La ejecución del script es una tarea y, después de su ejecución, la cola de microtareas será la primera en procesarse, el registro 'should be right after baz, before bar' en la consola.

Por último, se procesa la cola de tareas, se llama a la función baz y se registra 'baz' en la consola.


La siguiente puede ser una lectura útil para comprender la microtarea y la cola de tareas: Devoluciones de llamada asincrónicas de JavaScript - Promise y setTimeout

about 4 years ago · Juan Pablo Isaza Relatório

0

La documentación de MDN para Promise.prototype.then establece (el énfasis es mío):

Una vez que se cumple o se rechaza una Promesa, la función del controlador respectivo (onFulfilled o onRejected) se llamará de forma asincrónica (programada en el bucle de subproceso actual).

Puede encontrar el siguiente fragmento esclarecedor:

 Promise.resolve("I resolved").then((v) => console.log(v)); console.log("hello");

about 4 years ago · Juan Pablo Isaza Relatório

0

Si desea comprender el concepto asincrónico, debe ver este increíble video .

Intentaré explicarte la secuencia de cómo se ejecuta el código aquí.

En primer lugar, estamos inicializando todas las variables con funciones. Luego estamos llamando a foo() , y luego console.log('before baz') .

Lo que sucederá al llamar a foo es que foo ingresará a la pila . Y foo está conectado a la consola.

Luego se setTimeout(bar, 0) . setTimeout(bar, 0) siendo asincrónico , se llamará más tarde y se colocará en la cola de devolución de llamada (se llamará más tarde cuando la pila esté vacía). Por eso no vimos la consola de bar .

Después de esto, se myPromise.then(resolve => console.log(resolve)) . Y esta también es una llamada asíncrona . Por lo tanto, esto también se enviará a la cola de devolución de llamada.

Luego se ejecutará baz() . Y es por eso que estamos viendo un registro de baz después del foo .

Ahora recuerde, tenemos console.log('before bar') en la pila, por lo que se registrará primero. Y después de esto, se llamarán todos los elementos en la cola de devolución de llamada.

Tres cosas están registradas hasta ahora: - foo baz before bar

Ahora, lo bueno de las promesas es que se les da prioridad en la cola de devolución de llamada, sobre cualquier cosa. Entonces, incluso se llama a setTimeout antes de nuestra promesa, si se ejecuta la promesa, se priorizará .

Esa es la razón por la que 'should be right after baz, before bar' se llama antes de bar .

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda