J'ai du mal à comprendre javaScript promises
. J'ai écrit le code suivant:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Je vois immédiatement cela dans ma console développeur Chrome:
Mais après avoir attendu 5 secondes, le message passe automatiquement au noir comme cette image:
Je n'ai jamais vu ce comportement auparavant entre mon code javaScript et une console de développeur, où mon code javaScript peut "modifier le contenu existant" dans la console de développeur.
J'ai donc décidé de voir si la même situation se produit resolve
en écrivant ce code:
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
Mais dans cette situation, ma console de développeur n'affiche rien avant 5 secondes plus tard, sur laquelle elle s'imprime ensuite hello world
.
Pourquoi les resolve
et sont-ils reject
traités si différemment en termes de moment où ils sont invoqués?
SUPPLÉMENTAIRE
J'ai également écrit ce code:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);
Cela provoque plusieurs sorties vers la console du développeur. Erreur rouge au temps 0, le rouge devient noir au temps 5 secondes avec le texte errors hello world
, puis un nouveau message d'erreur au temps 6 secondes errors 2 hello world
, puis un message d'erreur rouge au temps 7 secondes. Maintenant, je suis très confus sur le nombre de fois où un est reject
effectivement invoqué ... Je suis perdu ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
peut être écrit de manière plus idiomatique et concisevar p = Promise.reject(Error("hello world"));
:-)Réponses:
Wow, c'est vraiment cool. Je n'avais jamais vu la console faire ça auparavant. (Il a cependant d' autres formes de comportement dynamique, alors ...) Voici ce qui se passe:
Dans le premier cas, l'exécution du code de tout ce qui se trouve en dehors
setTimeout
du code de votre rappel se termine et la pile d'exécution revient de sorte que seul le « code de plate-forme » (comme l'appelle la promesse / A +) s'exécute, pas le code JavaScript de l'espace utilisateur (pour le moment). À ce stade, la promesse est rejetée et rien n'a géré le rejet, il s'agit donc d'un rejet non géré et devtools vous le signale en tant que tel.Ensuite , cinq secondes plus tard, votre rappel s'exécute et attache un gestionnaire de rejet. À ce stade, le rejet n'est plus géré. Apparemment, Chrome / V8 / devtools fonctionnent ensemble pour supprimer l'avertissement de rejet non géré de la console. Ce que vous voyez apparaître à la place est ce que vous sortez dans votre gestionnaire de rejet via
console.log
. Si vous attachez le gestionnaire de rejet plus tôt, vous n'obtiendrez pas cette erreur de rejet non gérée.Cela ne se produit pas avec l'accomplissement car ne pas gérer l'accomplissement n'est pas une condition d'erreur. Ne pas gérer le rejet est.
la source