Archives pour la catégorie Javascript

Benchmark Node.JS: méthodes synchrones ou asynchrones ?

On dit souvent que les méthodes asynchrones apportent à Node.JS un avantage dans sa gestion des accès concurrents. On dit que pour une opération aussi coûteuse que de la lecture sur le disque par exemple, il saura gérer plus de connexions, et dans l’ensemble répondre plus vite si cette opération est faite en utilisant l’API asynchrone plutôt que l’API synchrone.

OK. Soit. En ce qui me concerne je n’ai pas le niveau technique pour comprendre les tenants et les aboutissants de tout ça, donc comment m’en convaincre? Et bien, benchmarkons :)

Partons d’un serveur HTTP très simple: il n’a qu’une page, qui affiche « coucou gamin » dès que le serveur a fini de lire un fichier local de quelques méga-octets.

Dans la suite de l’article je vais vous proposer 3 implémentations de ce serveur, et les résultats d’un test par Apache Bench.

Lire la suite

Bonnes pratiques pour gérer son code asynchrone en Javascript

Comme on l’a déjà vu, en Javascript, et principalement avec Node.JS, les appels à des méthodes non bloquantes exécutant leur traitement de manière asynchrone permet de faire du multi-tâche de manière très simple et performante. Néanmoins, un piège dans lequel on tombe rapidement est la cascade d’appels asynchrones.

On va prendre deux exemples, et voir comment les rendres plus lisibles dans la suite de cet article :)

Lire la suite

Présentation de Node.JS et du framework Express

Je me rends compte que dans ce blog je vous parle de Node.JS et d’Express, sans vous avoir jamais présenté ces technologies. Allez, revenons vite fait aux bases :)

Installation

Pour l’installation, je vous renvoie au site officiel, ou à un article en français par Atinux, mais globalement l’installation se résume à ces 3 lignes:

git clone https://github.com/ry/node.git
cd node
./configure && make && sudo make install

Présentation de Node.JS

Node.JS est un projet open-source se basant sur le moteur « V8 » de Chrome (il existe un fork « SpiderNode » par Mozilla, basé sur leur moteur SpiderMonkey).

Il s’agit donc finalement d’un simple interpréteur Javascript, exécutable, et enrichissant le langage avec sa propre API (accès au système de fichier, à la couche réseau, etc.). Ça permet, en résumé, d’exécuter des fichiers « .js » comme des scripts PHP, Python, Ruby, etc…

La spécificité n’est pas vraiment là (après tout, exécuter du JS en ligne de commande, ça se fait déjà), mais évidemment sur son API, toute entière orientée vers le non bloquant, c’est-à-dire que la plupart des commandes, notamment d’accès au système de fichier, rendront la main directement sans attendre la réponse du système, ceci étant largement simplifié par l’orientation évènementielle de Javascript. C’est ce choix de conception, ainsi que le choix du moteur V8 qui offre d’excellentes performances, qui permet d’écrire des applications avec d’excellents temps de réponse, et notamment des serveurs (web ou autres). Son API d’accès à la couche réseau (le protocole HTTP y est implémenté) couplé à cette capacité de gestion des accès concurrents en font évidemment un excellent candidat pour écrire des applications web.

Lire la suite

Node.js & Express: comment packager et partager ses applications

S’il y a bien une chose qui craint avec les technologies « cool » et récentes, c’est la doc. Et Node.JS (ou plutôt la grande majorité de ses modules, car l’API de Node elle-même est plutôt bien documentée) n’échappe pas à la règle, et les contributions de @visionmedia quoi que d’excellentes facture et très populaires, en sont hélas une illustration 😉 Du coup, il y a des fonctionnalités qu’on ne découvre qu’en farfouillant dans le code…

Je refléchissais en ce moment à un moyen de « packager » les applications Express dans Node.JS, de manière à les réutiliser. Naïvement, j’étais persuadé que ça n’était pas possible, et je suis parti dans le développement d’un framework permettant de simplifier ce packaging, avec des vues embarquées, etc… Naïf, oui, car évidemment cette fonctionnalité existe déjà dans Connect (la couche sous Express): quand on appelle app.use(une_autre_app), c’est comme si on « fusionnait » les deux applications. Ce comportement, ainsi que les valeurs de configuration disponibles, étant très mal documentées, je vais vous en parler ici :)

Lire la suite

Le point sur Javascript et l’héritage prototypal

Javascript n’est pas à proprement parler un langage objet, mais il dispose quand-même d’un opérateur new et de trucs qui ressemblent vachement à des propriétés et des méthodes. Donc par raccourci, on parle d’objet.

Dans les différents tutoriels sur le sujet, quand on aborde l’héritage, la méthode proposée est souvent celle-là:

1
2
3
4
5
6
7
8
9
10
function Animal(nom) { // class Animal
  this.nom = nom;
}
Animal.prototype.manger = function() { // Animal.manger()
  console.log('Miam!');
}
function Chien(nom) { // class Chien extends Animal
  Animal.call(this, nom); // super(nom)
}
Chien.prototype = new Animal(); // le fameux extends est là

Cette méthode n’est pas parfaite puisque pour implémenter l’héritage on va instancier un objet de la classe parente. WTF ? Du coup, faisons un petit tour des méthodes alternatives.

Lire la suite

Nodester: Hébergez vos applis NodeJS

J’ai découvert aujourd’hui Nodester: une plateforme d’hébergement d’application NodeJS. J’ai pu m’inscrire et faire les tous premiers tests, donc je vais vous faire part de mes impressions :)
Alors je vous le dis tout de suite: on est très loin des standards d’hébergement du monde PHP auquel je suis plus habitué. Exit le FTP (voire le SSH si on a de la chance), on a une API, avec un outil en ligne de commande, pour s’inscrire, créer, déployer et contrôler ses applications. Avertissement: Si vous testez, faites un peu attention à ce que vous faites, car je n’ai pas trouvé comment on supprimait son compte, ni comment on pouvait supprimer une application initialisée.

Note: J’ai aussi ouvert un compte sur DuoStack, mais je n’ai pas encore pris le temps de tester. On verra ça dans la semaine probablement 😉

Pré-requis

  • node
  • npm
  • une clé SSH (si vous utilisez déjà GitHub, pourquoi ne pas réutiliser celle que vous avez déjà l’habitude d’utiliser pour vos dépôts Git): en effet, le déploiement se fait par git push 😀

Lire la suite

Node.JS: l’avènement de la programmation asynchrone ?

On est plutôt habitué dans nos développements à faire du synchrone: on appelle une fonction, elle retourne une valeur quand elle a fini de travailler. Avec Javascript ça peut être totalement différent, par exemple avec Node.JS:

var fs = require("fs");
fs.readFile("fichier.txt", function(err, content) {
  if (err) {
    console.err(err);
  } else {
    console.log("file read: " + content.length + " bytes");
  }
}
console.log("after readFile");

En programmation synchrone, ce bout de code aurait lu le fichier, affiché « file read: X bytes » puis « after readFile ». Avec Node.JS ce n’est pas le cas, car toutes les fonctions systèmes ont une version synchrone (qui renvoie un résultat et lève une exception en cas d’erreur), et une vesion asynchrone (qui ne va rien renvoyer, rendre tout de suite la main, et prendre en paramètre un callback acceptant une éventuelle exception et le reste des paramètres). Lire la suite

Un bug bien classique qui permet de parler de JS et du scope

J’ai pu débugger récemment ce bout de code:

1
2
3
4
5
6
// on a n boutons, cliquer sur le bouton "i" a pour effet de cacher un lien correspondant
for (var i=0; i<nbCheckboxes; i++) {
  $('input[name="val' + i + '"]').click(function() {
    $('#link'+i).hide();
  });
}

Etrangement, quelque soit le bouton cliqué, rien ne se passait… Après vérification, à chaque clic jQuery essayait de me cacher le lien « #link5 » (sachant que j’avais 5 liens, numérotés de 0 à 4, ça pouvait moyennement marcher).

Mine de rien, ce petit bug peut arriver. Rarement, parce qu’on a rarement un code aussi mal foutu hein :) mais ça peut arriver. Et ce petit bug de rien du tout relève d’une feature mal comprise de Javascript que j’appelle les « contextes dynamiques », mais qui relève simplement de la portée des variables. Lire la suite