Puisque JavaScript s'exécute dans un seul thread, après qu'une requête AJAX est faite, que se passe-t-il réellement en arrière-plan? Je voudrais avoir un aperçu plus approfondi de cela, est-ce que quelqu'un peut nous éclairer?
Puisque JavaScript s'exécute dans un seul thread, après qu'une requête AJAX est faite, que se passe-t-il réellement en arrière-plan? Je voudrais avoir un aperçu plus approfondi de cela, est-ce que quelqu'un peut nous éclairer?
Réponses:
Sous les couvertures, javascript a une file d'attente d'événements. Chaque fois qu'un thread d'exécution javascript se termine, il vérifie s'il existe un autre événement dans la file d'attente à traiter. Si tel est le cas, il le retire de la file d'attente et déclenche cet événement (comme un clic de souris, par exemple).
Le réseau de code natif qui se trouve sous l'appel ajax saura quand la réponse ajax est terminée et un événement sera ajouté à la file d'attente d'événements javascript. La façon dont le code natif sait quand l'appel ajax est effectué dépend de l'implémentation. Il peut être implémenté avec des threads ou il peut également être lui-même piloté par des événements (cela n'a pas vraiment d'importance). Le point de l'implémentation est que lorsque la réponse ajax est terminée, un certain code natif saura que c'est fait et mettra un événement dans la file d'attente JS.
Si aucun Javascript n'est en cours d'exécution à ce moment, l'événement sera immédiatement déclenché, ce qui exécutera le gestionnaire de réponse ajax. Si quelque chose est en cours d'exécution à ce moment-là, l'événement sera traité lorsque le thread d'exécution javascript actuel se terminera. Il n'y a pas besoin d'interroger le moteur javascript. Lorsqu'un morceau de Javascript finit de s'exécuter, le moteur JS vérifie simplement la file d'attente d'événements pour voir s'il y a autre chose qui doit s'exécuter. Si tel est le cas, il fait sortir l'événement suivant de la file d'attente et l'exécute (en appelant une ou plusieurs fonctions de rappel enregistrées pour cet événement). Si rien n'est dans la file d'attente d'événements, l'interpréteur JS a du temps libre (garbage collection ou inactif) jusqu'à ce qu'un agent externe mette autre chose dans la file d'attente d'événements et la réveille.
Étant donné que tous les événements extérieurs passent par la file d'attente des événements et qu'aucun événement n'est jamais déclenché pendant que javascript exécute réellement autre chose, il reste un thread unique.
Voici quelques articles sur les détails:
.focus()
un élément et cela déclenche quelques autres événements tels qu'un événement "flou" sur l'élément avec le focus. Cet événement de flou se produit de manière synchrone et ne passe pas par la file d'attente d'événements, il se produirait donc immédiatement avant d'autres choses qui pourraient se trouver dans la file d'attente d'événements. En pratique, je n'ai jamais trouvé que c'était une préoccupation pratique.
Vous pouvez trouver ici une documentation très complète sur la gestion des événements en javascript.
Il est écrit par un gars travaillant sur l'implémentation javascript dans le navigateur Opera.
Plus précisément, regardez les titres: "Event Flow", "Event Queuing" et "Non-user Events": vous apprendrez que:
Remarque: le lien d'origine était: lien , mais il est maintenant mort.
Je veux élaborer un peu, concernant l'implémentation ajax mentionnée dans les réponses.
Bien que (régulier) exécution Javascript est pas multi-thread - comme il est indiqué bien dans les réponses ci - dessus - cependant , la manipulation réelle du AJAX responses
(ainsi que le traitement de la demande) est pas Javascript, et - le plus souvent - est multi-thread. (voir l' implémentation de la source chrome de XMLHttpRequest dont nous parlerons ci-dessus)
et je vais vous expliquer, prenons le code suivant:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- après l'étape 1), puis pendant l'exécution de votre code js (étape 2 et après), le navigateur commence le vrai travail de: 1. formatage d'une requête tcp 2. ouverture d'un socket 3. envoi d'en-têtes 4. prise de contact 5. envoi body 6. réponse en attente 7. lecture des en-têtes 8. lecture du corps etc. toute cette implémentation est généralement exécutée dans un thread différent en parallèle de l'exécution de votre code js. pour un exemple, l'implémentation de chrome mentionnée utilise Threadable Loader go digg-into 😉, (vous pouvez également avoir une impression en regardant l'onglet réseau d'un chargement de page, vous verrez quelques requêtes simultanées).
en conclusion, je dirais qu'au moins la plupart de vos opérations d'E / S peuvent être effectuées simultanément / asynchrone (et vous pouvez en profiter en utilisant un await par exemple). mais toutes les interactions avec ces opérations (l'émission, l'exécution du rappel js) sont toutes synchrones.