¿La devolución de llamada del constructor Promise se ejecuta de forma asincrónica?

Resuelto qnimate asked hace 9 años • 2 respuestas

Supongamos que tengo este código

function y(resolve, reject)
{
  console.log("Result");
  resolve();
}  

var promise = new Promise(y);

Lo que quiero saber es si la función yse ejecutará de forma asíncrona o no.

qnimate avatar Apr 30 '15 15:04 qnimate
Aceptado

Depende de la implementación de la promesa. Si comprobamos las especificaciones . Puede encontrar la especificación final aquí : dado que esta respuesta se escribió originalmente, se finalizó.

Aquí está el extracto relevante (puede encontrar la fuente original aquí )

  1. Deje que la finalización sea Call(executor, indefinido, «resolvingFunctions.[[Resolve]], resolviendoFunctions.[[Reject]]»).
  2. Si la finalización es una finalización abrupta, entonces
    • Deje que el estado sea Llamada (resolviendoFunciones.[[Rechazar]], indefinido, «finalización.[[valor]]»).
    • ReturnIfAbrupt(estado).

El estándar ES6 indica que el cumplimiento de una promesa es siempre asíncrono (consulte la sección 25.4.5.3 Promise.prototype.theny la sección 25.4.5.3.1 adjunta PerformPromiseThen). He colocado el material relevante a continuación.

RealizarPromesaEntonces

  1. De lo contrario, si el valor de la ranura interna [[PromiseState]] de la promesa se "cumple",
    • Sea value el valor de la ranura interna [[PromiseResult]] de la promesa.
    • Realizar EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, valor»).
  2. De lo contrario, si el valor de la ranura interna [[PromiseState]] de la promesa es "rechazado",
    • Sea la razón el valor de la ranura interna [[PromiseResult]] de la promesa.
    • Realizar EnqueueJob("PromiseJobs", PromiseReactionJob, «rejectReaction, motivo»).

TLDR : la función pasada a la promesa se ejecuta de forma sincrónica, pero thenlas llamadas posteriores siempre se ejecutan de forma asincrónica.

Dan avatar Apr 30 '2015 08:04 Dan

La otra respuesta lo demuestra , pero déjame hablar del razonamiento:

constructor de promesas

La devolución de llamada del constructor de promesa (como se especifica en la especificación de ES6 o en la implementación de las bibliotecas de especificaciones del constructor) siempre se ejecutará sincrónicamente; esto es para extraer una forma diferida (una forma más antigua de construcción de promesa) en caso de que necesite tener acceso. a la resolvedevolución de llamada:

var r;
var p new Promise(function(resolve, reject){
    r = resolve;
});
// use r here, for example
arr.push(r);

thendevoluciones de llamada

thensiempre se ejecutará de forma asincrónica, prácticamente todas las implementaciones de promesas principales (Native, bluebird, $q, Q, when, rsvp, promesa, jQuery (a partir de 3.0), etc.), así como las promesas nativas, se implementan (o implementan un superconjunto de, con más restricciones) Promesas/A+ .

Esta es exactamente la razón por la que Promises/A+ se creó a partir de Promises/A. Se conservarán las garantías asincrónicas y Zalgo no se liberará. (Ver también esta publicación ).

El hecho de que esto suceda (garantía asíncrona) es completamente intencional y previene activamente las condiciones de carrera . El código dentro y fuera de thensiempre se ejecutará en el mismo orden.

Aquí está la cita relevante:

onFulfilledo onRejectedno debe llamarse hasta que la pila de contexto de ejecución contenga solo código de plataforma. [3.1].

Benjamin Gruenbaum avatar Apr 30 '2015 09:04 Benjamin Gruenbaum