75 votes

Quand le corps d'une promesse est-il exécuté?

Supposons que j'ai les Promise :

 function doSomethingAsynchronous() {
  return new Promise((resolve) => {
    const result = doSomeWork();

    setTimeout(() => {
      resolve(result);
   }), 100);
  });
}
 

A quel moment doSomeWork() appelé? Est-ce juste après ou lorsque le Promise est construit? Sinon, dois-je faire explicitement quelque chose de plus pour m'assurer que le corps du Promise est exécuté?

71voto

dystroy Points 145126

Immédiatement, oui, par la spécification.

À partir de la MDN:

L'exécuteur de la fonction est exécuté immédiatement par la Promesse de la mise en œuvre, en passant résoudre et de rejeter les fonctions (l'exécuteur testamentaire est appelée avant que la Promesse du constructeur même renvoie l'objet créé)

Ici, il est dans la spécification ECMAScript (évidemment plus difficile à lire...): http://www.ecma-international.org/ecma-262/6.0/#sec-promise-executor

Cette garantie peut être important, par exemple lorsque vous êtes à la préparation de plusieurs promesses vous passez ensuite à l' all ou race, ou lorsque vos exécuteurs ont synchrone effets secondaires.

14voto

Icepickle Points 8243

Oui, lorsque vous construisez une Promise le premier paramètre est exécuté immédiatement.

En général, vous ne pouvez pas vraiment utiliser un promise dans la façon dont vous l'avez fait, comme avec votre application actuelle, il serait toujours synchrone.

Vous préférez mettre en œuvre avec un délai d'attente, ou appeler le résoudre fonction dans le cadre d'un callback ajax

function doSomethingAsynchronous() {
  return new Promise((resolve) => {
    setTimeout(function() {
      const result = doSomeWork();
      resolve(result);
    }, 0);
  });
}

L' setTimeout méthode serait alors appeler la fonction à la prochaine moment de l'événement de la file d'attente est gratuit

12voto

Moika Turns Points 81

Vous pouvez le voir ci-dessous le corps est exécuté immédiatement, juste en mettant le code synchrone dans le corps plutôt que asynchrone:

function doSomethingAsynchronous() {
  return new Promise((resolve) => {
    console.log("a");
    resolve("promise result");
  });
}
doSomethingAsynchronous();console.log("b");

Le résultat montre que la promesse corps est exécuté immédiatement (avant le " b " est imprimé):

a
b

Le résultat de la Promesse est retenu pour être publié à la une", puis " appel par exemple:

doSomethingAsynchronous().then(function(pr){console.log("c:"+pr);});console.log("b");

Résultat:

a
b
c:promise result

Même chose avec le code asynchrone dans le corps, à l'exception de la durée indéterminée de retard avant que la promesse est accomplie et puis peut être appelé (point 'c'). Donc, 'a' et 'b' sera imprimé dès que doSomethingAsynchronous() de retours, mais " c " s'affiche uniquement lorsque la promesse est accomplie ('résoudre' est appelé).

Ce qui semble étrange à la surface, une fois que l'appel à 'puis' est ajouté, est que " b "est imprimé avant le "c", même quand tout est synchrone. Sûrement " a "serait d'impression, puis" c "et enfin "b"? La raison pour laquelle 'a', 'b' et 'c' sont imprimées dans l'ordre parce que, peu importe si le code dans le corps est asynchrone ou de synchronisation, l'", puis " la méthode est toujours appelée de façon asynchrone par la Promesse.

Dans mon esprit, j'imagine que le "puis" méthode invoquée par quelque chose comme setTimeout(function(){then(pr);},0); dans la Promesse une fois 'résoudre' est appelé. I. e. l'exécution en cours de chemin doit se terminer avant que la fonction transmise vers", puis " sera exécuté.

Pas évident à partir de la Promesse de spécification pourquoi il le fait. Ma conjecture est qu'il garantit la cohérence des comportements concernant le moment", puis " s'appelle (toujours après l'exécution du thread se termine) qui est sans doute pour permettre de multiples Promises à être empilés/enchaînés avant le coup d'envoi de tous les then des appels dans la succession.

-1voto

epiqueras Points 520

Oui, l’appel étant synchrone, il sera immédiatement appelé avant d’attacher des ".sous" ou des ".catch "s.

La promesse sera déjà résolue au moment où le premier ".then" est attaché et la valeur de résolution sera immédiatement transmise.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X