Pourquoi node.js est-il asynchrone?

Personne n'a vraiment demandé cela (de toutes les «suggestions» que je reçois et aussi de la recherche avant que je ne le demandei ici).

Alors, pourquoi node.js est-il asynchrone?

D'après ce que j'ai déduit après quelques recherches:

Les langages comme PHP et Python sont des langages de script (je peux me tromper sur les langues en cours qui sont des langages de script) tandis que JavaScript n'est pas. (Je suppose que cela découle du fait que JS ne compile pas?)

Node.js s'exécute sur un seul thread alors que les langages de script utilisent plusieurs threads.

Asynchrone signifie apatride et que la connexion est persistante alors qu'elle est synchrone (presque) opposée.

Peut-être que la réponse est trouvée quelque part indiquée ci-dessus, mais je n'en suis toujours pas certaine.

Ma deuxième et dernière question relative à ce sujet est la suivante:

Est-ce que JavaScript pourrait être transformé en langue synchrone?

PS. Je sais que certains d'entre vous demanderont "pourquoi voudriez-vous rendre JS synchrone?" Dans vos réponses, mais la vérité est que je ne le fais pas. Je pose juste ces types de questions parce que je suis sûr qu'il y a plus de personnes que moi-même qui ont pensé à ces questions.

Node.js s'exécute sur un seul thread alors que les langages de script utilisent plusieurs threads.

Pas techniquement. Node.js utilise plusieurs threads, mais un seul thread d'exécution. Les threads d'arrière-plan sont destinés à traiter les IO pour faire fonctionner toutes les fonctions de la qualité asynchrone. Le traitement des threads de manière efficace est une douleur royale, de sorte que la meilleure option suivante consiste à s'exécuter dans une boucle d'événements afin que le code puisse s'exécuter alors que les threads d'arrière-plan sont bloqués sur les IO.

Asynchrone signifie apatride et que la connexion est persistante alors qu'elle est synchrone (presque) opposée.

Pas nécessairement. Vous pouvez conserver l'état dans un système asynchrone très facilement. Par exemple, en Javascript, vous pouvez utiliser bind() pour lier this à une fonction, préservant ainsi l'état explicitement lorsque la fonction retourne:

 function State() { // make sure that whenever doStuff is called it maintains its state this.doStuff = this.doStuff.bind(this); } State.prototype.doStuff = function () { }; 

Asynchronous signifie ne pas attendre qu'une opération soit terminée, mais l'enregistrement d'un auditeur à la place. Cela se produit tout le temps dans d'autres langues, notamment tout ce qui doit accepter les commentaires de l'utilisateur. Par exemple, dans une interface graphique Java, vous ne bloquez pas l'attente de l'utilisateur pour appuyer sur un bouton, mais vous enregistrez un auditeur avec l'interface utilisateur graphique.

Ma deuxième et dernière question relative à ce sujet est la suivante:

Est-ce que JavaScript pourrait être transformé en langue synchrone?

Techniquement, toutes les langues sont synchrones, même Javascript. Cependant, Javascript fonctionne beaucoup mieux dans un design asynchrone car il a été conçu pour être un seul thread.

Fondamentalement, il existe deux types de programmes:

  • CPU lié – la seule façon de l'accélérer est d'obtenir plus de temps CPU
  • IO bound- passe beaucoup de temps à attendre des données, donc un processeur plus rapide ne sera pas important

Les jeux vidéo, les croiseurs de numéros et les compilateurs sont liés à la CPU, alors que les serveurs Web et les interfaces graphiques sont généralement liés à l'IO. Javascript est relativement lent (en raison de sa complexité), donc il ne serait pas capable de concurrencer un scénario lié à la CPU (croyez-moi, j'ai écrit ma juste part de Javascript lié à la CPU).

Au lieu de coder en termes de classes et d'objets, Javascript se prête au codage en termes de fonctions simples qui peuvent être reliées ensemble. Cela fonctionne très bien en conception asynchrone, car les algorithmes peuvent être écrits pour traiter les données de façon incrémentielle. IO (en particulier le réseau IO) est très lent, donc il y a un peu de temps entre les paquets de données.

Exemple

Supposons que vous ayez 1000 connexions en direct, chacune fournissant un paquet toutes les millisecondes, et le traitement de chaque paquet prend 1 microseconde (très raisonnable). Supposons également que chaque connexion envoie 5 paquets.

Dans une application synchrone à un seul thread, chaque connexion sera traitée en série. Le temps total pris est (5 * 1 + 5 * .001) * 1000 millisecondes, ou ~ 5005 millisecondes.

Dans une application asynchrone à un seul thread, chaque connexion sera traitée en parallèle. Comme chaque paquet prend 1 milliseconde, et le traitement de chaque paquet prend .001 millisecondes, nous pouvons traiter le paquet de chaque connexion entre les paquets, notre formule devient: 1000 * .001 + 5 * 1 millisecondes, ou ~ 6 millisecondes.

La solution traditionnelle à ce problème était de créer plus de threads. Cela a résolu le problème de l'IO, mais lorsque le nombre de connexions a augmenté, l'utilisation de la mémoire (les threads coûtent beaucoup de mémoire) et l'utilisation de la CPU (multiplexage de 100 threads sur 1 noyau est plus difficile que 1 thread sur 1 noyau).

Cependant, il y a des inconvénients. Si votre application Web a également besoin de faire un gros encombrement, vous êtes SOL parce que pendant que vous croisez des nombres, les connexions doivent attendre. Threading résout ceci car le système d'exploitation peut échanger votre tâche à forte intensité de processeur lorsque les données sont prêtes pour un thread en attente d'IO. En outre, node.js est lié à un seul noyau, de sorte que vous ne pouvez pas profiter de votre processeur multi-cœur, sauf si vous faites tourner plusieurs instances et des demandes de proxy.

Javascript ne se compile pas dans n'importe quoi. Il est "évalué" au moment de l'exécution, tout comme PHP & Ruby. Par conséquent, c'est un langage de script comme PHP / Ruby. (C'est le nom officiel en fait ECMAScript).

Le «modèle» auquel adhère Node est un peu différent de PHP / Ruby. Node.js utilise une «boucle d'événement» (le thread unique) qui a pour but unique de prendre les requêtes réseau et de les traiter très rapidement et si, pour une raison quelconque, elle rencontre une opération qui prend un certain temps (demande d'API, requête de base de données – Essentiellement tout ce qui implique IO (entrée / sortie)), il passe cela sur un thread "travailleur" d'arrière-plan et se lance pour faire autre chose pendant que le thread du travailleur attend la tâche à accomplir. Lorsque cela se produit, la «boucle d'événements» principale prendra les résultats et continuera à les traiter.

PHP / Ruby suit un modèle de filetage. Essentiellement, pour chaque demande de réseau entrant, le serveur d'application fait pivoter un thread ou un processus isloated pour traiter la demande. Cela ne s'améliore pas très bien et l'approche de Node est citée comme l'une de ses principales forces par rapport à ce modèle.

Asynchrone signifie apatride et que la connexion est persistante alors qu'elle est synchrone (presque) opposée.

Non. Les instructions synchrones sont complétées dans un ordre naturel, du premier au dernier. Des instructions asynchrones signifient que si une étape dans le flux d'un programme prend un temps relativement long, le programme continuera d'exécuter les opérations et tout simplement retourner à cette opération une fois terminé.

Est-ce que JavaScript pourrait être transformé en langue synchrone?

Certaines opérations en JavaScript sont synchrones. D'autres sont asynchrones. Par exemple:

Opérations de blocage:

 for(var k = 0; k < 1; k = k - 1;){ alert('this will quickly get annoying and the loop will block execution') alert('this is blocked and will never happen because the above loop is infinite'); 

Asynchrone:

 jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); }); alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.'); 

Est-ce que JavaScript pourrait être transformé en langue synchrone?

Javascript n'est pas un "langage asynchrone"; Plutôt, node.js possède beaucoup d' API asynchrones. Asynchronous-ness est une propriété de l'API et non la langue. La facilité avec laquelle les fonctions peuvent être créées et passées dans javascript rend possible de passer des fonctions de rappel, qui est une façon de gérer le flux de contrôle dans une API asynchrone, mais il n'y a rien d'intrinsèque sur le javascript . Javascript peut facilement prendre en charge les API synchrones.

Pourquoi node.js est-il asynchrone?

Node.js favorise les API asynchrones car il est simple threadé. Cela lui permet de gérer efficacement ses propres ressources, mais exige que les opérations de longue durée ne soient pas bloquantes, et les API asynchrones permettent de contrôler le flux avec de nombreuses opérations de non-blocage.