web-dev-qa-db-fra.com

Pourquoi javascript ES6 Promises continue-t-il l'exécution après une résolution?

Si je comprends bien, une promesse peut résoudre () ou rejeter (), mais j'ai été surprise de découvrir que le code de la promesse continue de s'exécuter après l'appel d'une résolution ou d'un rejet.

Je pensais que résoudre ou refuser était une version de sortie ou de retour compatible avec les asynchrones, qui empêcherait toute exécution immédiate de la fonction.

Quelqu'un peut-il expliquer pourquoi l'exemple suivant montre parfois le fichier console.log après un appel de résolution:

var call = function() {
    return new Promise(function(resolve, reject) {
        resolve();
        console.log("Doing more stuff, should not be visible after a resolve!");
    });
};

call().then(function() {
    console.log("resolved");
});

jsbin

73

JavaScript a le concept de "run to completion" . À moins qu'une erreur ne soit générée, une fonction est exécutée jusqu'à ce qu'une instruction return ou sa fin soit atteinte. Les autres codes en dehors de la fonction ne peuvent pas interférer avec cela (sauf si, encore une fois, une erreur est renvoyée).

Si vous voulez que resolve() quitte votre fonction d'initialisation, vous devez l'ajouter par return:

return new Promise(function(resolve, reject) {
    return resolve();
    console.log("Not doing more stuff after a return statement");
});
116
Felix Kling

Les callbacks qui seront invoqués lorsque vous resolve une promesse sont toujours requis par la spécification pour être appelés de manière asynchrone. Cela garantit un comportement cohérent lors de l'utilisation de promesses pour une combinaison d'actions synchrones et asynchrones.

Par conséquent, lorsque vous appelez resolve, le rappel est mis en file d'attente, et l'exécution de la fonction continue immédiatement avec tout code suivant l'appel resolve().

Ce n'est que lorsque la boucle d'événement JS est rétablie que le rappel peut être retiré de la file d'attente et effectivement appelé.

18
Alnitak