¿La devolución de llamada del constructor Promise se ejecuta de forma asincrónica?
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 y
se ejecutará de forma asíncrona o no.
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í )
- Deje que la finalización sea Call(executor, indefinido, «resolvingFunctions.[[Resolve]], resolviendoFunctions.[[Reject]]»).
- 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.then
y la sección 25.4.5.3.1 adjunta PerformPromiseThen
). He colocado el material relevante a continuación.
RealizarPromesaEntonces
- 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»).
- 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 then
las llamadas posteriores siempre se ejecutan de forma asincrónica.
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 resolve
devolución de llamada:
var r;
var p new Promise(function(resolve, reject){
r = resolve;
});
// use r here, for example
arr.push(r);
then
devoluciones de llamada
then
siempre 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 then
siempre se ejecutará en el mismo orden.
Aquí está la cita relevante:
onFulfilled
oonRejected
no debe llamarse hasta que la pila de contexto de ejecución contenga solo código de plataforma. [3.1].