Les implications de Javascript étant un langage à thread unique

Si vous utilisez Javascript depuis un certain temps, vous rencontrerez peut-être l’expression le décrivant comme un langage à “thread unique”.

Qu’est-ce que cela signifie?

Javascript fonctionne sur un moteur V8 avec un tas de mémoire et une pile d’appels. JS étant monothread signifie qu’une seule instruction est exécutée à la fois. Avant de nous plonger dans ce que signifie fonctionner sur un seul thread, je veux d’abord passer en revue la terminologie que vous rencontrerez.

Je vais essayer d’expliquer cela le plus simplement possible. Pour mieux comprendre cela, vous devez comprendre une structure de données connue sous le nom de Stack (Last In, First Out).

Synchrone (ou sync) l’exécution fait généralement référence au code s’exécutant en séquence. En programmation synchronisée, le programme est exécuté ligne par ligne, une ligne à la fois. Chaque fois qu’une fonction est appelée, l’exécution du programme attend le retour de cette fonction avant de passer à la ligne de code suivante.

Par exemple, vous appelez quelqu’un et vous attendez qu’il décroche pour pouvoir lui parler. Vous ne faites rien d’autre jusqu’à ce qu’ils décrochent le téléphone.

Vous remplissez la demande de manière séquentielle.

const one() => {
     const two() => {
       console.log('5');
 }
    two();
}

Alors, que se passe-t-il sous la pile d’appels ?

Le travail de la pile d’appels consiste à remplir les instructions et à faire apparaître une instruction au fur et à mesure de son exécution.

Javascript est un langage monothread qui peut être non bloquant. Monothread dans le sens où il n’a qu’une seule pile d’appels. Tout ce qui se trouve en haut de la pile des appels est exécuté en premier.

Dans le programme ci-dessus, les fonctions sont exécutées séquentiellement.

Que se passe-t-il si nous avons une fonction qui est nécessaire pour soulever des charges lourdes ? Devrions-nous laisser l’utilisateur attendre que ce processus soit terminé ?

const one() {
      console.log("Hello");
}
const two () {
    for(i=0; i<= 100000000000000000000000; i++){
}
const three(){
       console.log("World");
}
one();
two();
three();

Considérez l'exemple ci-dessus, que se passe-t-il si notre deuxième fonction doit parcourir des nombres énormes, cela signifie-t-il que trois () doit attendre que deux () soit exécuté? Techniquement, oui !

Dans notre petit exemple, cela ne signifie peut-être pas grand-chose, mais si nous devons l'implémenter dans un projet réel, les utilisateurs ne pourront peut-être rien faire tant que le premier processus n'est pas terminé.

Asynchrone L'exécution (ou asynchrone) fait référence à une exécution qui ne s'exécute pas dans l'ordre dans lequel elle apparaît dans le code. En programmation asynchrone, le programme n'attend pas la fin de la tâche et peut passer à la tâche suivante.

Pour le mettre par exemple : vous appelez quelqu'un et pendant que vous attendez qu'il décroche le téléphone, vous faites aussi des courses.

Différents langages ont différentes manières d'implémenter l'exécution asynchrone. Le plus populaire est le multi-threading.

Java implémente le multi-threading en créant un thread enfant qui effectue sa propre exécution séparée, puis fusionne avec le thread parent.

Ceci, cependant, peut se heurter à un problème connu sous le nom de Deadlock, qui peut être traité par divers mécanismes de prévention des blocages.

Puisque nous sommes préoccupés par la mise en œuvre de l'exécution asynchrone en Javascript, voyons comment cela peut être fait

Essayez de l'exécuter sur la console et voyez ce qui se passe.

console.log('1');
setTimeout(()=> {
console.log('2')
}, 3000);
console.log('3');

Vous pouvez voir 1 3 et avec un bref délai 2 apparaît. Pourquoi cela arrive-t-il?

En un mot, l'implémentation asynchrone en Javascript se fait via une pile d'appels, une file d'attente de rappel, une API Web et une boucle d'événements.

Le travail de la pile d'appels, comme nous l'avons vu précédemment, consiste à vérifier quelle instruction se trouve en haut de la pile et à l'exécuter. S'il existe une instruction telle que setTimeout() qui nécessite un temps supplémentaire pour s'exécuter, la pile d'appels la fera apparaître et l'enverra à l'API Web.

Le travail d'une boucle d'événements consiste à vérifier en permanence si un événement s'est produit, comme un clic de souris ou un coup de clavier, afin qu'il puisse l'envoyer à la pile d'appels. Bien sûr, votre clic de souris aura une priorité d'exécution plus élevée qu'un chargement d'image.

En Javascript, toutes les instructions sont placées sur une pile d'appels. Lorsque la pile arrive à setTimeout, le moteur la considère comme une instruction d'API Web, la sort et l'envoie à l'API Web. Une fois que l'API Web a terminé l'exécution, elle arrivera dans la file d'attente de rappel.

Le moteur vérifie si la pile des appels est vide. S'il est vide, nous vérifions la file d'attente de rappel qui contient l'instruction setTimeout. La file d'attente de rappel l'envoie à la pile de rappel et l'instruction est exécutée.

L'autre façon de penser à cela est lorsque vous faites une demande d'API. Supposons, par exemple, que votre site Web doive récupérer une image à partir d'un serveur. Votre site Web doit-il refuser de charger d'autres parties jusqu'à ce que l'image arrive ? Ce serait une mauvaise expérience utilisateur.

Lorsque la pile d'appels voit qu'elle doit récupérer une image, elle apparaît et l'envoie à l'API Web et continue d'exécuter les fonctions restantes.

La réponse à la demande d'image est stockée dans la file d'attente de la pile d'appels.

Lorsque la pile d'appels est vide, la boucle d'événements qui s'exécute constamment examine la file d'attente de la pile d'appels si elle contient quelque chose. Si c'est le cas, dans notre cas, la réponse de la demande d'image. Il place la pile d'appels et exécute l'instruction.

L'avantage de cette procédure est que JavaScript n'a pas à se soucier du nombre de cœurs ou de nœuds sur lesquels un processeur s'exécute. Il n'y a qu'une seule pile d'appels pour cette implémentation.


Également publié ici.

CHARGEMENT EN COURS
. . . & commentaires Suite!

Leave a Comment