nodejs - promises javascript w3schools
¿Cuándo se ejecuta el cuerpo de una promesa? (4)
Supongamos que tengo la siguiente Promise
:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
const result = doSomeWork();
setTimeout(() => {
resolve(result);
}), 100);
});
}
¿En qué punto en el tiempo se doSomeWork()
? ¿Es inmediatamente después o como se construye la Promise
? Si no es así, ¿hay algo más que deba hacer explícitamente para asegurarme de que se ejecute el Cuerpo de la Promise
?
Inmediatamente, sí, por especificación.
Desde el MDN :
La función ejecutora se ejecuta de forma inmediata mediante la implementación de Promise, pasando las funciones de resolución y rechazo (se llama al ejecutor antes de que el constructor Promise devuelva el objeto creado)
Aquí está en la especificación ECMAScript (por supuesto, más difícil de leer ...): http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor
Esta garantía puede ser importante, por ejemplo, cuando está preparando varias promesas que luego pasa a all
o race
, o cuando sus ejecutores tienen efectos secundarios sincrónicos.
Puede ver desde abajo que el cuerpo se ejecuta de forma inmediata simplemente poniendo un código síncrono en el cuerpo en lugar de asíncrono:
function doSomethingAsynchronous() {
return new Promise((resolve) => {
console.log("a");
resolve("promise result");
});
}
doSomethingAsynchronous();console.log("b");
El resultado muestra que el cuerpo de la promesa se ejecuta inmediatamente (antes de que se imprima ''b''):
a
b
El resultado de la Promesa se conserva, para ser liberado a un ''entonces'' llamado por ejemplo:
doSomethingAsynchronous().then(function(pr){console.log("c:"+pr);});console.log("b");
Resultado:
a
b
c:promise result
Lo mismo ocurre con el código asíncrono en el cuerpo, excepto el retraso indeterminado antes de que se cumpla la promesa y se pueda llamar ''entonces'' (punto ''c''). Por lo tanto, ''a'' y ''b'' se imprimirán tan pronto como doSomethingAsynchronous()
regrese, pero ''c'' aparecerá solo cuando se cumpla la promesa (se llama ''resolver'').
Lo que parece extraño en la superficie, una vez que se agrega la llamada a ''then'', es que ''b'' se imprime antes de ''c'' incluso cuando todo está sincronizado. ¿Seguramente imprimirá ''a'', luego ''c'' y finalmente ''b''? La razón por la que ''a'', ''b'' y ''c'' se imprimen en ese orden es porque no importa si el código en el cuerpo es asíncrono o sincronizado, la Promesa siempre llama al método ''entonces'' de forma asíncrona. En mi mente, me imagino que el método ''entonces'' es invocado por algo como setTimeout(function(){then(pr);},0);
en la Promesa una vez que se llama ''resolver''. Es decir, la ruta de ejecución actual debe completarse antes de que se ejecute la función ''a continuación''. No es obvio por la especificación de Promise por qué hace esto. Mi conjetura es que garantiza un comportamiento consistente con respecto a cuándo se llama "entonces" (siempre después de que finalice el hilo de ejecución actual), lo que presumiblemente permite que se apilen / encadenen múltiples Promesas antes de iniciar todas las llamadas "entonces" en sucesión.
Sí, cuando construyes una Promesa, el primer parámetro se ejecuta inmediatamente.
En general, no usaría realmente una promesa de la forma en que lo hizo, ya que con su implementación actual, aún sería sincrónico.
Preferiría implementarlo con un tiempo de espera o llamar a la función de resolución como parte de una devolución de llamada ajax
function doSomethingAsynchronous() {
return new Promise((resolve) => {
setTimeout(function() {
const result = doSomeWork();
resolve(result);
}, 0);
});
}
El método setTimeout llamaría a la función en el siguiente momento posible en que la cola de eventos esté libre
Sí, ya que la llamada es sincrónica, se llamará inmediatamente, antes de adjuntar cualquier ".then" o ".catch" s.
La promesa ya se resolverá cuando se adjunte el primer ".then" e inmediatamente se transferirá el valor de resolución.