Maison > Article > interface Web > Une analyse approfondie des raisons pour lesquelles Promise est plus rapide que setTimeout()
Pourquoi Promise est-il plus rapide que setTimeout() ? L'article suivant analysera les raisons pour vous. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
Recommandations associées : "Tutoriel vidéo javascript"
Faisons une expérience. Qu'est-ce qui s'exécute plus rapidement : une promesse immédiatement résolue ou un setTimeout
immédiat (c'est-à-dire un setTimeout de 0 milliseconde) ?
Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); setTimeout(function timeout() { console.log('Timed out!'); }, 0); // 'Resolved!' // 'Timed out!'
promise.resolve(1)
est une fonction statique qui renvoie un promise
immédiatement résolu. setTimeout(callback, 0)
Exécutez la fonction de rappel avec un délai de 0毫秒
.
Nous pouvons voir qu'en imprimant 'Resolved!'
d'abord, puis en imprimant Timeout completed!
, la promesse qui se résout immédiatement est plus rapide que l'immédiate setTimeout
.
est dû au fait que Promise.resolve(true).then(...)
est appelé avant setTimeout(..., 0)
, le processus de promesse sera-t-il donc plus rapide ? Bonne question.
Donc, nous modifions légèrement les conditions expérimentales et appelons setTimeout(..., 0)
en premier :
setTimeout(function timeout() { console.log('Timed out!'); }, 0); Promise.resolve(1).then(function resolve() { console.log('Resolved!'); }); // 'Resolved!' // 'Timed out!'
setTimeout(..., 0)
est appelé avant Promise.resolve(true).then(...)
. Cependant, imprimez Resolved!
d'abord, puis 'Timed out!'
.
Pourquoi ça ?
Les questions liées au JS asynchrone peuvent trouver une réponse en étudiant la boucle d'événement. Passons en revue les principaux composants du fonctionnement du JS asynchrone.
[Le transfert d'image par lien externe a échoué, le site source peut avoir un mécanisme anti-sangsue, il est recommandé de sauvegarder l'image et de la télécharger directement (img-Lt9zVHTf-1611275604640)(/img/bVcMQaI)]
La pile d'appels est une structure LIFO (dernier entré, premier sorti) qui stocke le contexte d'exécution créé lors de l'exécution du code. En termes simples, la pile d'appels exécute ces fonctions.
L'API Web est l'endroit où les opérations asynchrones (récupération de requêtes, promesses, minuteries) et leurs rappels attendent d'être terminés.
**file d'attente des tâches (file d'attente des tâches) est une structure FIFO (premier entré, premier sorti)** qui enregistre les rappels pour les opérations asynchrones prêtes à être exécutées. Par exemple, une fonction de rappel d'un setTimeout()
qui expire ou un gestionnaire d'événements de clic sur un bouton prêt à être exécuté sont tous mis en file d'attente dans la file d'attente des tâches.
**job queue** est une structure FIFO (premier entré, premier sorti), qui enregistre les rappels de promise
prêts à être exécutés. Par exemple, le rappel resolve
ou reject
d'une promesse terminée est mis en file d'attente dans la file d'attente des tâches.
Enfin, la boucle d'événements écoute en permanence si la pile d'appels est vide. Si la pile d'appels est vide, la boucle d'événements examine la file d'attente des tâches ou la file d'attente des tâches et distribue tous les rappels prêts à être exécutés sur la pile d'appels.
Regardons cette expérience du point de vue de la boucle d'événements, et j'analyserai l'exécution du code étape par étape.
A) La pile d'appels exécute setTimeout(..., 0)
et planifie une minuterie timeout()
Le rappel est stocké dans l'API Web :
[Le transfert d'image du lien externe a échoué, le site source a peut-être échoué. mécanisme de protection anti-hotlink, il est recommandé de sauvegarder l'image et de la télécharger directement (img-SLk0AUa5-1611275604642)(/img/bVcMQdg)]
[Le transfert de l'image du lien externe a échoué, le site source a peut-être un mécanisme anti-sangsue, il est recommandé de sauvegarder l'image Upload directement (img-Zr7usYTK-1611275604643)(/img/bVcMQc9)]
B) La pile d'appels exécute Promise.resolve(true).then(resolve)
et planifie un promise
solution. resolved()
Le rappel est stocké dans l'API Web :
[Le transfert de l'image du lien externe a échoué. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img. -JTwSnLYS-1611275604646)(/img/ bVcMQdh)]
[Le transfert de l'image du lien externe a échoué. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img. -k5cRhqzN-1611275604648)(/img/bVcMQdi)]
C) La promesse est résolue immédiatement et le minuteur est exécuté immédiatement. De cette façon, le rappel du minuteur timeout()
entre dans la file d'attente des tâches et le promise
rappel resolve()
entre dans la file d'attente des travaux
[Le transfert d'image du lien externe a échoué. Le site source peut avoir un anti-. mécanisme de sangsue. Il est recommandé de sauvegarder l'image directement. Upload (img-iMfLB2YJ-1611275604649)(/img/bVcMQdS)]
D) Vient maintenant la partie intéressante : la file d'attente des tâches (microtâches) a une plus grande taille. priorité que la file d’attente des tâches (macrotâches). La boucle d'événements prend le rappel de promesse resolve()
de la file d'attente des tâches et le place sur la pile d'appels. Ensuite, la pile d'appels exécute le rappel de promesse resolve()
:
[Le transfert de l'image du lien externe a échoué. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (. img-nnqfgoo1-1611275604650)(/img /bVcMQey)]
E) Enfin, la boucle d'événements retire le rappel du minuteur timeout()
de la file d'attente des tâches vers la pile d'appels. Ensuite, la pile d'appels exécute le rappel du minuteur timeout()
:
[Le transfert de l'image du lien externe a échoué. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (. img-Fj54WaI0-1611275604650)(/ img/bVcMQeB)]
La pile d'appels est vide et l'exécution du script est terminée.
Pourquoi les promesses immédiatement résolues sont-elles traitées plus rapidement que les minuteurs d'exécution immédiate ?
En raison des priorités des boucles d'événements, la file d'attente des tâches (qui stocke les rappels setTimeout()
implémentés) a une priorité plus élevée que la file d'attente des tâches (qui stocke les rappels Promise
expirés).
Adresse originale : https://dmitripavlutin.com/javascript-promises-settimeout/
Auteur : Milos Protic
Adresse de traduction : https://segmentfault .com/a/1190000038769853
Pour plus de connaissances liées à la programmation informatique, veuillez visiter : Vidéo de programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!