web-dev-qa-db-fra.com

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 de demander ici).

Alors, pourquoi node.js est-il asynchrone?

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

Des langages comme PHP et Python sont des langages de script (je peux me tromper sur les langages réels qui sont des langages de script)) alors que JavaScript ne l'est pas. (Je suppose que cela dérive du fait que JS ne compile pas?)

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

Asynchrone signifie sans état et que la connexion est persistante tandis que synchrone est (presque) l'opposé.

Peut-être que la réponse se trouve quelque part indiquée ci-dessus, mais je ne suis toujours pas sûr.

Ma deuxième et dernière question liée à ce sujet est la suivante:

JavaScript pourrait-il être transformé en un langage 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 simplement ce genre de questions parce que je suis sûr qu'il y a plus de gens que moi-même qui ont pensé à de telles questions.

47
Joe

Node.js s'exécute sur un seul thread tandis 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 à gérer IO pour faire fonctionner toute la qualité asynchrone. La gestion efficace des threads est une douleur royale, donc la meilleure option suivante est de s'exécuter dans une boucle d'événements afin que le code puisse s'exécute alors que les threads d'arrière-plan sont bloqués sur IO.

Asynchrone signifie sans état et que la connexion est persistante tandis que synchrone est (presque) l'opposé.

Pas nécessairement. Vous pouvez conserver l'état dans un système asynchrone assez facilement. Par exemple, en Javascript, vous pouvez utiliser bind() pour lier un this à une fonction, préservant ainsi explicitement l'état 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 () {
};

Asynchrone signifie ne pas attendre la fin d'une opération, mais enregistrer un écouteur à la place. Cela se produit tout le temps dans d'autres langues, notamment tout ce qui doit accepter l'entrée de l'utilisateur. Par exemple, dans une GUI Java, vous ne bloquez pas l'attente de l'utilisateur pour appuyer sur un bouton, mais vous enregistrez un écouteur avec la GUI.

Ma deuxième et dernière question liée à ce sujet est la suivante:

JavaScript pourrait-il être transformé en un langage synchrone?

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

Fondamentalement, il existe deux types de programmes:

  • Processeur lié - la seule façon de l'accélérer est d'obtenir plus de temps processeur
  • IO lié - passe beaucoup de temps à attendre les données, donc un processeur plus rapide n'aura pas d'importance

Les jeux vidéo, les calculateurs de nombres et les compilateurs sont liés au processeur, tandis que les serveurs Web et les interfaces graphiques sont généralement IO liés. Javascript est relativement lent (en raison de sa complexité), il ne serait donc pas en mesure de pour participer à un scénario lié au processeur (croyez-moi, j'ai écrit ma juste part de Javascript lié au processeur).

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 enchaînées. Cela fonctionne très bien dans la conception asynchrone, car les algorithmes peuvent être écrits pour traiter les données de manière incrémentielle au fur et à mesure qu'elles entrent. IO (en particulier IO réseau)) est très lent, donc il y a pas mal de temps entre les paquets des données.

Exemple

Supposons que vous ayez 1000 connexions actives, chacune délivrant 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. Étant donné que chaque paquet prend 1 milliseconde et que le traitement de chaque paquet prend 0,001 milliseconde, nous pouvons traiter chaque paquet de connexion entre les paquets, donc 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 IO, mais ensuite, lorsque le nombre de connexions a augmenté, l'utilisation de la mémoire (les threads coûtent beaucoup de mémoire) et l'utilisation du processeur (multiplexer 100 threads sur 1 cœur est plus difficile que 1). fil sur 1 noyau).

Cependant, il y a des inconvénients. Si votre application Web doit également effectuer un calcul intensif, vous êtes SOL car pendant que vous calculez des chiffres, les connexions doivent attendre. Le threading résout ce problème car le système d'exploitation peut s'échanger votre tâche gourmande en ressources CPU lorsque les données sont prêtes pour un thread en attente sur IO. En outre, node.js est lié à un seul cœur, vous ne pouvez donc pas tirer parti de votre processeur multicœur à moins que vous ne lanciez plusieurs instances et demandes de proxy .

51
beatgammit

Javascript ne se compile en rien. Il est "évalué" au moment de l'exécution, tout comme PHP & Ruby. C'est donc un langage de script comme PHP/Ruby. (Son nom officiel est 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 le seul but de prendre les requêtes réseau et les manipulant très rapidement, et si pour une raison quelconque, il rencontre une opération qui prend un certain temps (requête API, requête de base de données - essentiellement tout ce qui implique des E/S (entrée/sortie)), il le transmet à un thread `` travailleur '' d'arrière-plan et s'éteint pour faire autre chose pendant que le thread de travail attend la fin de la longue tâche. Lorsque cela se produit, la "boucle d'événement" principale prendra les résultats et continuera à les traiter.

PHP/Ruby suivant un modèle de threading. Essentiellement, pour chaque demande réseau entrante, le serveur d'applications tourne un thread ou processus isolé pour gérer la demande. Cela n'évolue 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 sans état et que la connexion est persistante tandis que synchrone est (presque) l'opposé.

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

JavaScript pourrait-il être transformé en un langage 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.');
32
Casey Flynn

JavaScript pourrait-il être transformé en un langage synchrone?

Javascript n'est pas un "langage asynchrone"; plutôt, node.js a beaucoup de asynchrones API. Asynchronous-ness est une propriété de l'API et non du langage. La facilité avec laquelle les fonctions peuvent être créées et transmises en javascript facilite la transmission 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 de intrinsèquement asynchrone à propos de 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 monothread. Cela lui permet de gérer efficacement ses propres ressources, mais nécessite que les opérations de longue durée soient non bloquantes, et les API asynchrones sont un moyen de permettre le contrôle du flux avec de nombreuses opérations non bloquantes.

20
Trevor Dixon