Cet article résume 4 points clés de Node.js pour les développeurs.
1. E/S non bloquantes ou asynchrones
Étant donné que Node.js est un framework côté serveur, l'une de ses tâches principales est de gérer les requêtes du navigateur. Dans un système d'E/S traditionnel, chaque requête est émise après l'arrivée de la requête précédente. C’est ce qu’on appelle bloquer les E/S. Le serveur bloquera les autres requêtes pour traiter la requête en cours, provoquant une attente du navigateur.
Node.js ne gère pas les E/S de cette façon. Si le traitement d'une requête prend beaucoup de temps, Node.js enverra la requête à une boucle d'événements et continuera à traiter la requête suivante dans la pile d'appels. Lorsque la demande différée est traitée, elle en informe Node.js et le navigateur répond.
Ce qui suit utilise un exemple pour illustrer.
Blocage des E/S
// take order for table 1 and wait... var order1 = orderBlocking(['Coke', 'Iced Tea']); // once order is ready, take order back to table. serveOrder(order1); // once order is delivered, move on to another table. // take order for table 2 and wait... var order2 = orderBlocking(['Coke', 'Water']); // once order is ready, take order back to table. serveOrder(order2); // once order is delivered, move on to another table. // take order for table 3 and wait... var order3 = orderBlocking(['Iced Tea', 'Water']); // once order is ready, take order back to table. serveOrder(order3); // once order is delivered, move on to another table.
Dans cet exemple de restaurant, le serveur reçoit les instructions du menu, attend que le repas soit traité, puis amène le repas à table une fois le repas traité. Pendant que le serveur attendait que son repas soit préparé, il refusait les commandes de menu des autres clients.
E/S non bloquantes
// take order for table 1 and move on... orderNonBlocking(['Coke', 'Iced Tea'], function(drinks){ return serveOrder(drinks); }); // take order for table 2 and move on... orderNonBlocking(['Beer', 'Whiskey'], function(drinks){ return serveOrder(drinks); }); // take order for table 3 and move on... orderNonBlocking(['Hamburger', 'Pizza'], function(food){ return serveOrder(food); });
En mode non bloquant, le serveur informera le chef des instructions de menu qu'il a reçues, puis recevra les instructions pour la table suivante. Lorsque la première table de repas sera terminée, il servira les plats de cette table et continuera ensuite à recevoir les instructions des autres convives. De cette façon, le serveur ne perdra pas de temps à bloquer des instructions.
2. Prototype
Le prototype est un concept complexe en JS. Dans les langages de mécanisme d'héritage typiques tels que Java ou C++, afin de réaliser la réutilisation du code, vous devez d'abord créer une classe, puis générer des objets via elle ou générer des objets via une extension de classe. Mais il n’existe pas de concept similaire de classes dans JS. Après avoir créé un objet dans JS, vous devez étendre l'objet ou créer un nouvel objet via celui-ci. C’est ce qu’on appelle l’héritage prototypique.
Chaque objet JS est connecté à un objet prototype et hérite des propriétés de cet objet. Chaque objet est associé à un Object.prototype JS prédéfini. Si vous recherchez des propriétés d'objet via obj.propName ou obj['propName'> mais que la recherche échoue, vous pouvez essayer de rechercher via obj.hasOwnProperty('propName'). Le runtime JS recherchera dans le prototype Rechercher les propriétés dans un fichier. objet. Si la propriété n'existe pas dans la chaîne de prototypes, une valeur non définie sera renvoyée.
Illustrons avec l'exemple suivant :
if (typeof Object.create !== 'function') { Object.create = function (o) { var F = function () {}; F.prototype = o; return new F(); }; var otherPerson = Object.create(person);
Lorsque vous créez un nouvel objet, vous devez sélectionner un objet basé sur un prototype. Ici, nous avons ajouté une méthode create à la fonction objet. La méthode create crée un objet basé sur un autre objet et le transmet en tant que paramètre.
Quand on change un nouvel objet, son prototype reste inchangé. Cependant, lorsque nous modifions un objet prototype, la modification affecte tous les objets basés sur ce prototype.
3.Modules
Si vous avez déjà utilisé des packages en Java, les composants Node.js sont similaires. Sinon, ne vous inquiétez pas : les composants sont en fait de simples fichiers JS utilisés pour implémenter des fonctions spécifiques. Le but du modèle de composants est de faciliter votre travail. Pour utiliser des composants, vous devez importer des fichiers JS tout comme vous importez des packages en JAVA. Il existe deux types de composants dans Node.js
Modules principaux - Les modules principaux sont précompilés en conjonction avec la bibliothèque Node.js. Son objectif est d'ouvrir les fonctions fréquemment utilisées par les programmeurs et d'éviter la duplication du travail. Les composants de base communs incluent HTTP, URL, ÉVÉNEMENTS, SYSTÈME DE FICHIERS, etc.
Modules définis par l'utilisateur (UserDefined Modules) - Les modules définis par l'utilisateur sont des composants fournis aux utilisateurs pour implémenter des fonctions spécifiques. Lorsque les composants de base ne suffisent pas à répondre aux besoins des programmeurs, des composants personnalisés peuvent s'avérer utiles.
Les composants sont extraits via la fonction require. S'il s'agit d'un composant principal, le paramètre est le nom du composant. S'il s'agit d'un composant défini par l'utilisateur, le paramètre est son chemin de composant dans le système de fichiers. Par exemple :
// extract a core module like this var http = require('http); // extract a user defined module like this var something = require('./folder1/folder2/folder3/something.js');
4. 回调(Callbacks)
在JS中,函数是第一类对象。也就是说你可以像对常规对象那样对函数进行所有操作。例如指派函数到一个变量,把这些作为参数传给方法,把它们声明为对象的属性,甚至是把它们从函数里返回。
回调在JS中是异步函数,可以作为参数传递给其它函数或从其它函数里执行或返回而后再执行。这是回调的基本概念。
当我们把一个回调函数作为参数传递给另外的函数时,我们传递的仅仅是函数的定义;换言之,我们不会知道回调函数的执行时间。这完全依赖于回调函数机制。它会在稍后某个时间点进行回调调用。这是Node.js的非阻塞或异步行为的基本概念,可用下例进行说明:
setTimeout(function() { console.log("world"); }, 2000) console.log("hello");
这是一个最简单的调用。我们把一个匿名函数作为参数进行传递,作用是为setTimeout函数进行控制台的输出记录登记。因为这仅仅是个函数定义,我们不知道函数何时会被执行。这取决于setTimeout函数的second参数,即2S后。
首先,second记录语句记录了对控制台的输出,2S后,在回调函数中的记录语句记录了输出的内容。
// output hello world
写在最后
以上4点对Node.js开发者来说是要彻底理解和掌握的,建议多动手来好好体会这4个要点的含义。