Qu'est-ce que Node.js? [fermé]


506

Je ne comprends pas bien ce que Node.js est tout au sujet. C'est peut-être parce que je suis principalement développeur d'applications Web. Qu'est-ce que c'est et à quoi ça sert?

Jusqu'à présent, je comprends que:

  1. Le modèle de programmation est axée sur l' événement, en particulier la façon dont il gère les E / S .
  2. Il utilise JavaScript et l'analyseur est V8 .
  3. Il peut être facilement utilisé pour créer des applications serveur simultanées.

Mes compréhensions sont-elles correctes? Si oui, alors quels sont les avantages des E / S éventuelles, est-ce juste plus pour les choses simultanées? En outre, la direction de Node.js doit-elle devenir un modèle de programmation basé sur JavaScript (basé sur V8)?

Réponses:


213

Je pense que les avantages sont:

  1. Développement Web en langage dynamique (JavaScript) sur une VM incroyablement rapide (V8). Il est beaucoup plus rapide que Ruby, Python ou Perl.

  2. Capacité à gérer des milliers de connexions simultanées avec un minimum de frais généraux sur un seul processus.

  3. JavaScript est parfait pour les boucles d'événements avec des objets de fonction et des fermetures de première classe. Les gens savent déjà comment l'utiliser de cette façon après l'avoir utilisé dans le navigateur pour répondre aux événements déclenchés par l'utilisateur.

  4. Beaucoup de gens connaissent déjà JavaScript, même ceux qui ne prétendent pas être des programmeurs. C'est sans doute le langage de programmation le plus populaire.

  5. L'utilisation de JavaScript sur un serveur Web ainsi que sur le navigateur réduit la non-correspondance d'impédance entre les deux environnements de programmation qui peuvent communiquer des structures de données via JSON qui fonctionnent de la même façon des deux côtés de l'équation. Le code de validation de formulaire en double peut être partagé entre le serveur et le client, etc.


1
@postfuturist: Il fonctionne bien contre de nombreuses alternatives. Il bat Java 6 assez facilement dans de nombreux cas également. Soigné!
Adam Crossland

1
@postfuturist Je pense que vous avez comparé avec java 6 -Xint. Essayez de comparer avec java 6 -server
fedesilva

@iJK yammer.com est une application fonctionnelle de node.js
Gerard Banasig

1
C'est drôle, j'écrivais JScript en ASP il y a 10 ans, donc je pouvais (a) éviter les horreurs de VBScript, (b) utiliser le même langage sur le client et le serveur, et (c) réutiliser ma bibliothèque JS et celle des autres pour la manipulation des chaînes ... etc.
Antony Quinn

4
@Pourquoi avez-vous édité ce post pour "Connaissances héritées" uniquement? Je ne pense pas que 212 personnes auraient voté pour ce message si vous l'aviez écrit depuis le début.
Julien Fouilhé

619

J'utilise Node.js au travail et le trouve très puissant. Forcé de choisir un mot pour décrire Node.js, je dirais "intéressant" (qui n'est pas un adjectif purement positif). La communauté est dynamique et en croissance. JavaScript, malgré ses bizarreries, peut être un excellent langage pour coder. Et vous repenserez quotidiennement votre propre compréhension des "meilleures pratiques" et des modèles de code bien structuré. Il y a une énorme énergie d'idées qui coule dans Node.js en ce moment, et y travailler vous expose à toutes ces pensées - une excellente haltérophilie mentale.

Node.js en production est certainement possible, mais loin du déploiement "clé en main" apparemment promis par la documentation. Avec Node.js v0.6.x, "cluster" a été intégré à la plate-forme, fournissant l'un des blocs de construction essentiels, mais mon script "production.js" est toujours ~ 150 lignes de logique pour gérer des choses comme la création du journal répertoire, recyclage des travailleurs morts, etc. Pour un service de production "sérieux", vous devez également être prêt à limiter les connexions entrantes et à faire tout ce que fait Apache pour PHP . Pour être juste, Ruby on Rails a exactement ce problème. Il est résolu via deux mécanismes complémentaires: 1) Mettre Ruby on Rails / Node.Apache / Lighttd ). Le serveur Web peut servir efficacement le contenu statique, accéder à la journalisation, réécrire les URL, mettre fin à SSL , appliquer les règles d'accès et gérer plusieurs sous-services. Pour les demandes qui atteignent le service de nœud réel, le serveur Web procède par procuration à la demande. 2) Utiliser un framework comme Unicorn qui gérera les processus de travail, les recyclera périodiquement, etc. Je n'ai pas encore trouvé de framework de service Node.js qui semble complètement cuit; il peut exister, mais je ne l'ai pas encore trouvé et j'utilise toujours ~ 150 lignes dans mon "production.js" roulé à la main.

La lecture de frameworks comme Express donne l'impression que la pratique standard consiste à tout servir par le biais d'un service Node.js polyvalent ... "app.use (express.static (__ dirname + '/ public'))" . Pour les services et le développement à faible charge, c'est probablement bien. Mais dès que vous essayez d'imposer une charge de temps importante à votre service et de le faire fonctionner 24h / 24 et 7j / 7, vous découvrirez rapidement les motivations qui poussent les grands sites à avoir un code C bien cuit et durci comme Nginx qui gère leur site et gère tous des demandes de contenu statique (... jusqu'à ce que vous configuriez un CDN , comme Amazon CloudFront )). Pour un point de vue quelque peu humoristique et sans vergogne, voyez ce gars .

Node.js trouve également de plus en plus d'utilisations hors service. Même si vous utilisez autre chose pour servir du contenu Web, vous pouvez toujours utiliser Node.js comme outil de construction, en utilisant des modules npm pour organiser votre code, Browserify pour l' assembler en un seul actif et uglify-js pour le réduire pour le déploiement . Pour traiter avec le Web, JavaScript est une correspondance d'impédance parfaite et fréquemment, ce qui en fait la voie d'attaque la plus simple. Par exemple, si vous voulez parcourir un tas de charges utiles de réponse JSON , vous devez utiliser mon module de soulignement-CLI , la ceinture utilitaire de données structurées.

Avantages / inconvénients:

  • Pro: Pour un serveur, l'écriture de JavaScript sur le backend a été un "médicament de passerelle" pour apprendre les modèles d'interface utilisateur modernes. Je ne redoute plus d'écrire du code client.
  • Pro: tend à encourager une vérification des erreurs appropriée (l'erreur est renvoyée par pratiquement tous les rappels, harcelant le programmeur pour le gérer; également, async.js et d'autres bibliothèques gèrent le paradigme "échec si l'une de ces sous-tâches échoue" beaucoup mieux que le code synchrone typique )
  • Pro: certaines tâches intéressantes et normalement difficiles deviennent triviales - comme obtenir l'état des tâches en vol, communiquer entre les employés ou partager l'état du cache
  • Pro: énorme communauté et des tonnes de grandes bibliothèques basées sur un solide gestionnaire de paquets (npm)
  • Con: JavaScript n'a pas de bibliothèque standard. Vous vous habituez tellement à importer des fonctionnalités que cela vous semble bizarre lorsque vous utilisez JSON.parse ou une autre méthode de construction qui ne nécessite pas l'ajout d'un module npm. Cela signifie qu'il existe cinq versions de tout. Même les modules inclus dans le "noyau" Node.js ont cinq autres variantes si vous n'êtes pas satisfait de l'implémentation par défaut. Cela conduit à une évolution rapide, mais aussi à un certain niveau de confusion.

Vers un modèle simple à un processus par demande ( LAMP ):

  • Pro: extensible à des milliers de connexions actives. Très rapide et très efficace. Pour une flotte Web, cela pourrait signifier une réduction de 10 fois le nombre de boîtes requises par rapport à PHP ou Ruby
  • Pro: L'écriture de motifs parallèles est facile. Imaginez que vous devez récupérer trois (ou N) blobs de Memcached . Faites cela en PHP ... venez-vous d'écrire du code pour récupérer le premier blob, puis le second, puis le troisième? Wow, c'est lent. Il existe un module PECL spécial pour résoudre ce problème spécifique pour Memcached, mais que faire si vous souhaitez récupérer des données Memcached en parallèle avec votre requête de base de données? Dans Node.js, parce que le paradigme est asynchrone, avoir une requête Web faisant plusieurs choses en parallèle est très naturel.
  • Inconvénients: le code asynchrone est fondamentalement plus complexe que le code synchrone, et la courbe d'apprentissage initiale peut être difficile pour les développeurs sans une solide compréhension de ce que signifie réellement l'exécution simultanée. Pourtant, c'est beaucoup moins difficile que d'écrire tout type de code multithread avec verrouillage.
  • Inconvénient: si une requête à calcul intensif s'exécute pendant, par exemple, 100 ms, elle bloquera le traitement des autres requêtes qui sont traitées dans le même processus Node.js ... AKA, coopérative-multitâche . Cela peut être atténué avec le modèle Web Workers (spin-off d'un sous-processus pour faire face à la tâche coûteuse). Alternativement, vous pouvez utiliser un grand nombre de travailleurs Node.js et ne laisser que chacun gérer une seule demande simultanément (toujours assez efficace car il n'y a pas de recyclage de processus).
  • Con: Exécution d' un système de production est beaucoup plus compliqué qu'un CGI modèle comme Apache + PHP, Perl , Ruby , etc. exceptions non gérées fera baisser l'ensemble du processus, la logique qui nécessite de redémarrer les travailleurs défectueux (voir le groupe ). Les modules avec du code natif bogué peuvent bloquer brutalement le processus. Chaque fois qu'un travailleur décède, toutes les demandes qu'il traitait sont abandonnées, de sorte qu'une API buggy peut facilement dégrader le service pour d'autres API cohébergées.

Contre l'écriture d'un "vrai" service en Java / C # / C (C? Vraiment?)

  • Pro: Faire asynchrone dans Node.js est plus facile que de faire de la sécurité des threads ailleurs et offre sans doute un plus grand avantage. Node.js est de loin le paradigme asynchrone le moins douloureux dans lequel j'ai jamais travaillé. Avec de bonnes bibliothèques, il n'est que légèrement plus difficile que d'écrire du code synchrone.
  • Pro: Pas de bugs de multithreading / verrouillage. Certes, vous investissez dès le départ dans l'écriture de code plus verbeux qui exprime un flux de travail asynchrone approprié sans opérations de blocage. Et vous devez écrire des tests et faire fonctionner la chose (c'est un langage de script et les noms de variables de doigté gras ne sont détectés qu'au moment du test unitaire). MAIS, une fois que vous l'avez fait fonctionner, la surface pour les heisenbugs - des problèmes étranges qui ne se manifestent qu'une fois sur un million de pistes - cette surface est juste beaucoup plus faible. Les taxes écrivant le code Node.js sont fortement chargées en amont dans la phase de codage. Ensuite, vous avez tendance à vous retrouver avec du code stable.
  • Pro: JavaScript est beaucoup plus léger pour exprimer les fonctionnalités. Il est difficile de le prouver avec des mots, mais JSON , le typage dynamique, la notation lambda, l'héritage prototypique, les modules légers, peu importe ... cela a tendance à prendre moins de code pour exprimer les mêmes idées.
  • Con: Peut-être que vous aimez vraiment, vraiment les services de codage en Java?

Pour une autre perspective sur JavaScript et Node.js, consultez De Java à Node.js , un article de blog sur les impressions et les expériences d'un développeur Java en apprenant Node.js.


Modules Lorsque vous envisagez un nœud, gardez à l'esprit que votre choix de bibliothèques JavaScript DÉFINIRA votre expérience. La plupart des gens en utilisent au moins deux, un assistant de modèle asynchrone (Step, Futures, Async) et un module de sucre JavaScript ( Underscore.js ).

Helper / JavaScript Sugar:

  • Underscore.js - utilisez ceci. Simplement fais-le. Cela rend votre code agréable et lisible avec des choses comme _.isString () et _.isArray (). Je ne sais pas vraiment comment vous pourriez écrire du code sécurisé autrement. En outre, pour améliorer la ligne de commande-fu, consultez ma propre Underscore-CLI .

Modules de motifs asynchrones:

  • Étape - une façon très élégante d'exprimer des combinaisons d'actions en série et en parallèle. Ma recommandation personnelle. Voir mon article sur le code Step.
  • Futures - beaucoup plus flexible (est-ce vraiment une bonne chose?) Pour exprimer la commande à travers les exigences. Peut exprimer des choses comme «démarrer a, b, c en parallèle. Lorsque A et B terminent, démarrer AB. Lorsque A et C terminent, démarrer AC». Une telle flexibilité nécessite plus de soin pour éviter les bogues dans votre flux de travail (comme ne jamais appeler le rappel ou l'appeler plusieurs fois). Voir le post de Raynos sur l'utilisation des futures (c'est le post qui m'a fait "obtenir" des futures).
  • Async - bibliothèque plus traditionnelle avec une méthode pour chaque modèle. J'ai commencé par cela avant ma conversion religieuse à l'étape et la réalisation ultérieure que tous les modèles d'Async pouvaient être exprimés en étape avec un seul paradigme plus lisible.
  • TameJS - Écrit par OKCupid, c'est un précompilateur qui ajoute un nouveau langage primitif "wait" pour écrire avec élégance des workflows série et parallèles. Le motif a l'air incroyable, mais il nécessite une pré-compilation. Je suis toujours en train de me décider sur celui-ci.
  • StreamlineJS - concurrent de TameJS. Je me penche vers Tame, mais vous pouvez vous faire votre propre opinion.

Ou pour tout savoir sur les bibliothèques asynchrones, consultez cet entretien avec les auteurs.

Cadre Web:

  • Express Great Ruby on Rails-esk framework pour l'organisation de sites Web. Il utilise JADE comme moteur de modèle XML / HTML, ce qui rend la construction de HTML beaucoup moins pénible, voire même élégante.
  • jQuery Bien qu'il ne s'agisse pas techniquement d'un module de noeud, jQuery devient rapidement une norme de facto pour l'interface utilisateur côté client. jQuery fournit des sélecteurs de type CSS pour «interroger» des ensembles d'éléments DOM qui peuvent ensuite être exploités (gestionnaires d'ensemble, propriétés, styles, etc.). Dans la même veine, le framework CSS Bootstrap de Twitter , Backbone.js pour un modèle MVC et Browserify.js pour assembler tous vos fichiers JavaScript en un seul fichier. Ces modules deviennent tous de facto des normes, vous devriez donc au moins les vérifier si vous n'en avez pas entendu parler.

Essai:

  • JSHint - Doit utiliser; Je ne l'ai pas utilisé au début, ce qui semble maintenant incompréhensible. JSLint ajoute un tas de vérifications de base que vous obtenez avec un langage compilé comme Java. Parenthèses incompatibles, variables non déclarées, types de nombreuses formes et tailles. Vous pouvez également activer différentes formes de ce que j'appelle le "mode anal" où vous vérifiez le style des espaces blancs et ainsi de suite, ce qui est OK si c'est votre tasse de thé - mais la vraie valeur vient de l'obtention de commentaires instantanés sur le numéro de ligne exact où vous avez oublié une fermeture ")" ... sans avoir à exécuter votre code et à frapper la ligne incriminée. « JSHint » est une variante plus configurable de Douglas Crockford de JSLint .
  • Compétiteur de moka aux voeux que je commence à préférer. Les deux cadres gèrent assez bien les bases, mais les modèles complexes ont tendance à être plus faciles à exprimer dans Mocha.
  • Vows Vows est vraiment assez élégant. Et il imprime un joli rapport (--spec) vous montrant quels cas de test ont réussi / échoué. Passez 30 minutes à l'apprendre et vous pouvez créer des tests de base pour vos modules avec un minimum d'effort.
  • Zombie - Test sans tête pour HTML et JavaScript utilisant JSDom comme "navigateur" virtuel. Des trucs très puissants. Combinez-le avec Replay pour obtenir des tests déterministes rapides comme l'éclair du code dans le navigateur.
  • Un commentaire sur la façon de "penser" aux tests:
    • Le test n'est pas facultatif. Avec un langage dynamique comme JavaScript, il y a très peu de contrôles statiques. Par exemple, la transmission de deux paramètres à une méthode qui attend 4 ne s'arrêtera pas avant l'exécution du code. Barre assez basse pour créer des bugs en JavaScript. Les tests de base sont essentiels pour combler l'écart de vérification avec les langues compilées.
    • Oubliez la validation, faites simplement exécuter votre code. Pour chaque méthode, mon premier cas de validation est "rien ne casse", et c'est le cas qui se déclenche le plus souvent. Prouver que votre code s'exécute sans lancer attrape 80% des bogues et fera tellement pour améliorer votre confiance dans le code que vous vous retrouverez à revenir et à ajouter les cas de validation nuancés que vous avez ignorés.
    • Commencez petit et brisez la barrière inertielle. Nous sommes tous paresseux et pressés par le temps, et il est facile de voir les tests comme un "travail supplémentaire". Commencez donc petit. Écrivez le cas de test 0 - chargez votre module et signalez le succès. Si vous vous forcez à faire tout cela, la barrière inertielle aux tests est brisée. C'est <30 min pour le faire votre première fois, y compris la lecture de la documentation. Maintenant, écrivez le cas de test 1 - appelez l'une de vos méthodes et vérifiez que «rien ne casse», c'est-à-dire que vous ne récupérez pas d'erreur. Le cas de test 1 devrait vous prendre moins d'une minute. Avec l'inertie disparue, il devient facile d'étendre progressivement votre couverture de test.
    • Faites évoluer maintenant vos tests avec votre code. Ne soyez pas intimidé par ce à quoi ressemblerait le test de bout en bout "correct" avec des serveurs fictifs et tout ça. Le code commence simple et évolue pour gérer de nouveaux cas; les tests devraient aussi. Lorsque vous ajoutez de nouveaux cas et une nouvelle complexité à votre code, ajoutez des cas de test pour appliquer le nouveau code. Lorsque vous trouvez des bogues, ajoutez des vérifications et / ou de nouveaux cas pour couvrir le code défectueux. Lorsque vous déboguez et que vous perdez confiance en un morceau de code, revenez en arrière et ajoutez des tests pour prouver qu'il fait ce que vous pensez qu'il est. Capturez des chaînes d'exemples de données (provenant d'autres services que vous appelez, de sites Web que vous supprimez, peu importe) et insérez-les dans votre code d'analyse. Quelques cas ici, une validation améliorée là-bas, et vous vous retrouverez avec un code très fiable.

Consultez également la liste officielle des modules Node.js recommandés. Cependant, le Wiki Node Modules de GitHub est beaucoup plus complet et une bonne ressource.


Pour comprendre Node, il est utile de considérer quelques-uns des choix de conception clés:

Node.js est basé sur les événements et asynchrone / non bloquant. Les événements, comme une connexion HTTP entrante, déclencheront une fonction JavaScript qui fait un peu de travail et lance d'autres tâches asynchrones comme la connexion à une base de données ou l'extraction de contenu d'un autre serveur. Une fois ces tâches lancées, la fonction d'événement se termine et Node.js se rendort. Dès que quelque chose se produit, comme la connexion à la base de données établie ou le serveur externe répondant avec du contenu, les fonctions de rappel se déclenchent et plus de code JavaScript s'exécute, ce qui peut potentiellement déclencher encore plus de tâches asynchrones (comme une requête de base de données). De cette façon, Node.js entrelacera avec plaisir les activités de plusieurs workflows parallèles, exécutant toutes les activités débloquées à tout moment. C'est pourquoi Node.js fait un excellent travail en gérant des milliers de connexions simultanées.

Pourquoi ne pas simplement utiliser un processus / thread par connexion comme tout le monde?Dans Node.js, une nouvelle connexion n'est qu'une très petite allocation de tas. Faire tourner un nouveau processus prend beaucoup plus de mémoire, un mégaoctet sur certaines plates-formes. Mais le coût réel est le surcoût associé au changement de contexte. Lorsque vous avez 10 ^ 6 threads de noyau, le noyau doit faire beaucoup de travail pour déterminer qui doit exécuter ensuite. Un tas de travail a été consacré à la création d'un planificateur O (1) pour Linux, mais en fin de compte, c'est juste beaucoup plus efficace d'avoir un seul processus événementiel que 10 ^ 6 processus en compétition pour le temps CPU. En outre, dans des conditions de surcharge, le modèle multi-processus se comporte très mal, affamant les services d'administration et de gestion critiques, en particulier SSHD (ce qui signifie que vous ne pouvez même pas vous connecter à la boîte pour comprendre à quel point il est vraiment vissé).

Node.js est UNIQUE FILETÉ et FREE LOCK . Node.js, en tant que choix de conception très délibéré, n'a qu'un seul thread par processus. Pour cette raison, il est fondamentalement impossible pour plusieurs threads d'accéder simultanément aux données. Ainsi, aucun verrou n'est nécessaire. Les fils sont durs. Vraiment vraiment dur. Si vous n'y croyez pas, vous n'avez pas fait assez de programmation threadée. Obtenir un verrouillage correct est difficile et entraîne des bogues très difficiles à détecter. L'élimination des verrous et du multi-threading fait disparaître l'une des classes de bugs les plus méchantes. Cela pourrait être le plus grand avantage du nœud.

Mais comment puis-je profiter de ma boîte à 16 cœurs?

Deux façons:

  1. Pour les tâches de calcul lourdes comme le codage d'image, Node.js peut lancer des processus enfants ou envoyer des messages à des processus de travail supplémentaires. Dans cette conception, vous auriez un thread gérant le flux d'événements et N processus effectuant des tâches de calcul lourdes et mâchant les 15 autres CPU.
  2. Pour faire évoluer le débit sur un service Web, vous devez exécuter plusieurs serveurs Node.js sur une seule boîte, un par cœur, à l'aide d'un cluster (avec Node.js v0.6.x, le module "cluster" officiel lié ici remplace la version learnboost qui a une API différente). Ces serveurs Node.js locaux peuvent alors entrer en concurrence sur un socket pour accepter de nouvelles connexions, en équilibrant la charge entre elles. Une fois qu'une connexion est acceptée, elle devient étroitement liée à un seul de ces processus partagés. En théorie, cela semble mauvais, mais en pratique, cela fonctionne assez bien et vous permet d'éviter le mal de tête d'écrire du code thread-safe. Cela signifie également que Node.js obtient une excellente affinité de cache CPU, en utilisant plus efficacement la bande passante mémoire.

Node.js vous permet de faire des choses vraiment puissantes sans transpirer. Supposons que vous ayez un programme Node.js qui effectue diverses tâches, écoute les commandes sur unport TCP , code certaines images, peu importe. Avec cinq lignes de code, vous pouvez ajouter un portail de gestion Web basé sur HTTP qui affiche l'état actuel des tâches actives. Cela est facile à faire:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");

Vous pouvez maintenant frapper une URL et vérifier l'état de votre processus en cours. Ajoutez quelques boutons, et vous avez un "portail de gestion". Si vous avez un script Perl / Python / Ruby en cours d'exécution, simplement "lancer un portail de gestion" n'est pas exactement simple.

Mais JavaScript n'est-il pas lent / mauvais / diabolique / apparition du diable? JavaScript a des bizarreries bizarres, mais avec "les bonnes parties" il y a un langage très puissant là-dedans, et en tout cas, JavaScript est LE langage sur le client (navigateur). JavaScript est là pour rester; d'autres langues le ciblent en tant qu'IL, et des talents de classe mondiale sont en concurrence pour produire les moteurs JavaScript les plus avancés. En raison du rôle de JavaScript dans le navigateur, une énorme quantité d'efforts d'ingénierie sont déployés pour rendre le JavaScript flamboyant rapide. V8est le dernier et le meilleur moteur javascript, au moins pour ce mois. Il fait exploser les autres langages de script en termes d'efficacité ET de stabilité (en vous regardant, Ruby). Et cela ne fera que s'améliorer avec d'énormes équipes travaillant sur le problème chez Microsoft, Google et Mozilla, en compétition pour construire le meilleur moteur JavaScript (Ce n'est plus un "interprète" JavaScript car tous les moteurs modernes font des tonnes de JITcompilation sous le capot avec interprétation uniquement comme solution de rechange pour le code à exécution unique). Oui, nous souhaitons tous pouvoir corriger quelques-uns des choix de langage JavaScript les plus étranges, mais ce n'est vraiment pas si mal. Et le langage est tellement flexible que vous ne codez vraiment pas JavaScript, vous codez Step ou jQuery - plus que tout autre langage, en JavaScript, les bibliothèques définissent l'expérience. Pour créer des applications Web, vous devez à peu près tout de même connaître JavaScript, donc le codage avec lui sur le serveur a une sorte de synergie de compétences. Cela ne m'a pas fait peur d'écrire du code client.

De plus, si vous détestez VRAIMENT JavaScript, vous pouvez utiliser du sucre syntaxique comme CoffeeScript . Ou tout autre élément qui crée du code JavaScript, comme Google Web Toolkit (GWT).

En parlant de JavaScript, qu'est-ce qu'une "fermeture"? - Une façon plutôt élégante de dire que vous conservez des variables à portée lexicale sur les chaînes d'appels. ;) Comme ça:

var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
    database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();

Voyez comment vous pouvez simplement utiliser "myData" sans rien faire de gênant comme le ranger dans un objet? Et contrairement à Java, la variable "myData" n'a pas besoin d'être en lecture seule. Cette puissante fonctionnalité de langage rend la programmation asynchrone beaucoup moins verbeuse et moins douloureuse.

L'écriture de code asynchrone sera toujours plus complexe que l'écriture d'un simple script à un seul thread, mais avec Node.js, ce n'est pas beaucoup plus difficile et vous obtenez de nombreux avantages en plus de l'efficacité et de l'évolutivité de milliers de connexions simultanées. ..


"la variable 'myData' ne doit pas être en lecture seule" - semble que vous souhaitiez la garder immuable la plupart du temps pour éviter les problèmes de concurrence, non?
Nick

1
@Nick - c'est faux. Les "problèmes de concurrence" sont atténués par le fait que le nœud est un thread unique. Le verrouillage du nœud n'existe tout simplement pas; il n'est pas nécessaire dans un paradigme monothread.
Dave Dopson


1
ps, note latérale - Je l'ai en fait édité suffisamment de fois pour que le message devienne "wiki communautaire" (le seuil est de 10 modifications). J'ai pensé à tort que c'était une sorte d'honneur, alors qu'en fait, cela bloque simplement le gain de réputation des votes positifs. Finalement, l'un des électeurs avant le statut CW a cliqué sur "annuler le vote" (avec un peu de chance, par accident :) et j'ai perdu la réputation ... confus j'ai déposé meta.stackexchange.com/questions/129941/… et j'ai été formé dans quelle "Communauté" Wiki "signifie en fait. Les mods ont eu la gentillesse de supprimer le statut CW. :)
Dave Dopson

1
@John - mon commentaire de débogage s'applique également à asnyc vanilla. Pour interrompre le débogage, tout ce que je dois faire est d'encapsuler un appel de fonction dans "process.nextTick (...)". Ensuite, quand il lance, ma trace de pile commence par process.nextTick; pas si utile. Ce que je veux vraiment savoir, c'est: "quelle pile a planifié process.nextTick?" J'appelle ces données des "chaînes causales", et cela me rappelle "CauseBy" dans la gestion des exceptions Java ... les lancements de code de bas niveau, le code de niveau intermédiaire attrape l'exception LL et lève FrameworkMethodFailedException - sans "CauseBy", la pile de la LL le code serait perdu.
Dave Dopson

85

V8 est une implémentation de JavaScript. Il vous permet d'exécuter des applications JavaScript autonomes (entre autres).

Node.js est simplement une bibliothèque écrite pour V8 qui fait des E / S éventuelles. Ce concept est un peu plus compliqué à expliquer, et je suis sûr que quelqu'un répondra avec une meilleure explication que je ... L'essentiel est que , plutôt que de faire une entrée ou de sortie et d' attendre que cela se produise, il vous suffit ne pas attendre pour qu'il se termine. Par exemple, demandez la dernière heure de modification d'un fichier:

// Pseudo code
stat( 'somefile' )

Cela peut prendre quelques millisecondes ou quelques secondes. Avec les E / S éventuelles, vous déclenchez simplement la demande et au lieu d'attendre, vous attachez un rappel qui s'exécute lorsque la demande se termine:

// Pseudo code
stat( 'somefile', function( result ) {
  // Use the result here
} );
// ...more code here

Cela ressemble beaucoup au code JavaScript dans le navigateur (par exemple, avec la fonctionnalité de style Ajax ).

Pour plus d'informations, vous devriez consulter l'article Node.js est vraiment passionnant, ce qui était mon introduction à la bibliothèque / plate-forme ... Je l'ai trouvé assez bon.


4
Comment les E / S événementielles sont-elles implémentées sans utiliser de verrous, à l'aide de threads, de processus, de fermetures? Et j'ai le sentiment que les concepts sont assez similaires à ceux de la programmation fonctionnelle et d'Erlang.
Jeff

1
Il est implémenté comme une simple boucle d'événements, pour autant que je sache. v8 a déjà la fonctionnalité de rappel / etc, comme n'importe quelle implémentation javascript.
rfunduk

2
La boucle d'événements IO de node.js signifie qu'à tout moment donné, une seule chose au plus est en cours. Je vois deux gains importants: il n'y a pas de surcharge de commutation de thread, donc node.js est très rapide, et deuxièmement, de nombreux bogues de concurrence typiques Java sont connus pour ne sont pas possibles.
2010

1
"Comment les E / S événementielles sont-elles implémentées sans utiliser ... de fermetures?" JavaScript prend en charge les fermetures et elles sont utilisées tout le temps dans node.js (fonctions anonymes et dans l'exemple ici).
panzi

@panzi: Je n'ai pas remarqué que Jeffrey a inclus des fermetures dans sa liste de choses. node.js est implémenté «sans». Évidemment, chaque fonction en javascript est une fermeture autour de sa portée :)
rfunduk

35

Node.js est un outil de ligne de commande open source conçu pour le code JavaScript côté serveur. Vous pouvez télécharger une archive tar , compiler et installer la source. Il vous permet d'exécuter des programmes JavaScript.

Le JavaScript est exécuté par le V8 , un moteur JavaScript développé par Google qui est utilisé dans le navigateur Chrome . Il utilise une API JavaScript pour accéder au réseau et au système de fichiers.

Il est populaire pour ses performances et sa capacité à effectuer des opérations parallèles.

Comprendre node.js est la meilleure explication de node.js que j'ai trouvée jusqu'à présent.

Voici quelques bons articles sur le sujet.


13

Les fermetures sont un moyen d'exécuter du code dans le contexte dans lequel il a été créé.

Par souci de concordance, cela signifie que vous pouvez définir des variables, puis lancer une fonction d' E / S non bloquante et lui envoyer une fonction anonyme pour son rappel.

Une fois la tâche terminée, la fonction de rappel s'exécutera dans le contexte des variables, c'est la fermeture.

La raison pour laquelle les fermetures sont si bonnes pour écrire des applications avec des E / S non bloquantes est qu'il est très facile de gérer le contexte des fonctions s'exécutant de manière asynchrone.


8

Deux bons exemples concernent la façon dont vous gérez les modèles et utilisez les améliorations progressives avec. Vous avez juste besoin de quelques morceaux légers de code JavaScript pour le faire fonctionner parfaitement.

Je vous recommande fortement de regarder et de lire ces articles:

Choisissez n'importe quelle langue et essayez de vous rappeler comment vous géreriez vos modèles de fichiers HTML et ce que vous deviez faire pour mettre à jour un nom de classe CSS unique dans votre structure DOM (par exemple, un utilisateur a cliqué sur un élément de menu et vous voulez qu'il soit marqué comme "sélectionné" et mettre à jour le contenu de la page).

Avec Node.js, c'est aussi simple que de le faire en code JavaScript côté client. Obtenez votre nœud DOM et appliquez votre classe CSS à cela. Obtenez votre nœud DOM et innerHTML votre contenu (vous aurez besoin de code JavaScript supplémentaire pour ce faire. Lisez l'article pour en savoir plus).

Un autre bon exemple est que vous pouvez rendre votre page Web compatible avec JavaScript activé ou désactivé avec le même morceau de code. Imaginez que vous ayez sélectionné une date en JavaScript qui permettrait à vos utilisateurs de choisir n'importe quelle date à l'aide d'un calendrier. Vous pouvez écrire (ou utiliser) le même morceau de code JavaScript pour le faire fonctionner avec votre JavaScript activé ou désactivé.


7

Il existe une très bonne analogie avec les fast-foods qui explique le mieux le modèle événementiel de Node.js, voir l'article complet, Node.js, Doctor's Offices and Fast Food Restaurants - Understanding Event-driven Programming

En voici un résumé:

Si le joint de restauration rapide suivait un modèle traditionnel à base de fil, vous commanderiez votre nourriture et attendriez en ligne jusqu'à ce que vous la receviez. La personne derrière vous ne pourra pas commander tant que votre commande n'aura pas été effectuée. Dans un modèle axé sur les événements, vous commandez votre nourriture, puis vous sortez de la file d'attente. Tout le monde est alors libre de commander.

Node.js est piloté par les événements, mais la plupart des serveurs Web sont basés sur des threads. York explique comment fonctionne Node.js:

  • Vous utilisez votre navigateur Web pour effectuer une demande de "/about.html" sur un serveur Web Node.js.

  • Le serveur Node.js accepte votre demande et appelle une fonction pour récupérer ce fichier à partir du disque.

  • Pendant que le serveur Node.js attend la récupération du fichier, il traite la prochaine demande Web.

  • Lorsque le fichier est récupéré, une fonction de rappel est insérée dans la file d'attente des serveurs Node.js.

  • Le serveur Node.js exécute cette fonction qui dans ce cas afficherait la page "/about.html" et la renverrait à votre navigateur Web. "


6

Eh bien, je comprends que

  • L'objectif de Node est de fournir un moyen simple de créer des programmes réseau évolutifs.
  • Node est similaire dans sa conception et influencé par des systèmes comme Ruby's Event Machine ou Python's Twisted.
  • E / S par événement pour javascript V8.

Pour moi, cela signifie que vous aviez raison dans les trois hypothèses. La bibliothèque semble prometteuse!


1
La plupart du temps, je trouve que la page est assez vague.
Jeff

6

N'oubliez pas non plus de mentionner que le V8 de Google est TRÈS rapide. Il convertit en fait le code JavaScript en code machine avec les performances correspondantes du binaire compilé. Donc, avec toutes les autres grandes choses, c'est incroyablement rapide.


3

Q: Le modèle de programmation est commandé événement, en particulier la façon dont il gère les E / S .

Correct. Il utilise des rappels, donc toute demande d'accès au système de fichiers entraînerait l'envoi d'une demande au système de fichiers, puis Node.js commencerait à traiter sa prochaine demande. Il ne s'inquiéterait de la demande d'E / S qu'une fois qu'il obtiendrait une réponse du système de fichiers, auquel cas il exécuterait le code de rappel. Cependant, il est possible d'effectuer des demandes d'E / S synchrones (c'est-à-dire des demandes de blocage). Il appartient au développeur de choisir entre asynchrone (rappels) ou synchrone (en attente).

Q: Il utilise JavaScript et l'analyseur est V8.

Oui

Q: Il peut être facilement utilisé pour créer des applications serveur simultanées.

Oui, bien que vous ayez besoin de coder manuellement beaucoup de JavaScript. Il serait peut-être préférable de regarder un framework, tel que http://www.easynodejs.com/ - qui est fourni avec une documentation en ligne complète et un exemple d'application.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.