1. Analyse d'ouverture
Dans le chapitre précédent, nous avons appris la connaissance théorique de base des NodeJS. Il est crucial de comprendre cette connaissance théorique. Dans les chapitres suivants, nous apprendrons progressivement divers modules dans les documents officiels. Eh bien, il est temps que le protagoniste de cet article apparaisse sur scène. Mondial
Jetons un coup d'œil à la définition officielle:
Objets globaux Ces objets sont disponibles dans tous les modules. Certains de ces objets ne sont pas réellement dans la portée globale mais dans la portée du module - cela sera noté.
Ces objets sont disponibles dans tous les modules. En fait, certains objets ne sont pas dans la portée globale de la portée, mais dans sa portée du module - celles-ci seront identifiées.
Dans les navigateurs, la portée de niveau supérieur est la portée mondiale. Cela signifie que dans les navigateurs si vous êtes dans la gamme globale var something définira une variable globale.
Dans le nœud, c'est différent. La portée de niveau supérieur n'est pas la portée mondiale; var something à l'intérieur d'un module de nœud sera local à ce module.
Je pense que tout le monde ne devrait pas être familier avec le concept d'objets mondiaux. Dans le navigateur, la portée le plus élevé est la portée globale, ce qui signifie que si vous utilisez "Var" pour définir une variable dans la portée globale, cette variable sera définie comme une portée globale.
Mais c'est différent dans NodeJS. Le plus haut niveau de portée n'est pas la portée mondiale. Dans un module, une variable est définie à l'aide de "var" et cette variable n'est que dans la portée de ce module.
Dans NodeJS, variables, fonctions ou méthodes définies dans un module ne sont disponibles que dans ce module, mais peuvent être transmis à l'extérieur du module via l'utilisation de l'objet Exportation.
Cependant, dans Node.js, il existe toujours une portée globale, c'est-à-dire que vous pouvez définir des variables, des fonctions ou des classes qui ne nécessitent pas de chargement de modules.
Dans le même temps, certaines méthodes globales et objets globaux globaux sont prédéfinis à l'avance, qui sont les espaces de noms globaux dans NodeJS. Toutes les variables, fonctions ou objets globaux sont des valeurs d'attribut de l'objet.
Dans l'environnement de fonctionnement des REP, vous pouvez observer les détails de l'objet global via l'instruction suivante, voir la figure ci-dessous:
Je parlerai des objets de valeur d'attribut pertinents montés sur l'objet global un par un ci-dessous.
(1), processus
Process {objet} L'objet de processus. Veillez la section Object Process.
processus {objet} Il s'agit d'un objet de processus. J'expliquerai en détail dans les chapitres suivants, mais ici, je vais d'abord éliminer une API pour en parler.
process.nexttick (rappel)
Sur la prochaine boucle autour de la boucle d'événement, appelez ce rappel. Ce n'est pas un alias simple à Settimeout (FN, 0), c'est beaucoup plus efficace. Il fonctionne généralement avant que d'autres événements d'E / S ne tirent, mais il y a quelques exceptions. Voir process.mAxTtickDepth ci-dessous.
Fonction de rappel de rappel dans la boucle suivante de la boucle d'événement. Ce n'est pas un alias simple pour la fonction SetTimeout (FN, 0), car il est beaucoup plus efficace.
Cette fonction peut appeler notre fonction de rappel avant toute E / S. Si vous souhaitez effectuer certaines opérations après la création d'objets et avant que l'opération d'E / S ne se produise, cette fonction est très importante pour vous.
Beaucoup de gens ne comprennent pas l'utilisation de Process.NextTick () dans Node.js. Jetons un coup d'œil à quel processus.NextTick () est et comment l'utiliser.
Node.js est unique. À l'exception du système IO, un seul événement sera traité en même temps lors de son processus de sondage d'événements. Vous pouvez considérer le sondage d'événements comme une grande file d'attente, à chaque moment, le système ne traitera qu'un seul événement.
Même si votre ordinateur a plusieurs cœurs CPU, vous ne pouvez pas gérer plusieurs événements en parallèle en même temps. Mais cette fonctionnalité rend Node.js adapté au traitement des applications d'E / S, mais pas pour les applications informatiques CPU.
Dans chaque application d'E / S, il vous suffit de définir une fonction de rappel pour chaque entrée et sortie, et elles seront automatiquement ajoutées à la file d'attente de traitement du sondage des événements.
Une fois l'opération d'E / S terminée, cette fonction de rappel sera déclenchée. Le système continuera ensuite de traiter d'autres demandes.
Dans ce mode de traitement, process.NextTick () signifie définir une action et laisser cette action être exécutée au moment où le prochain événement interroge. Jetons un coup d'œil à un exemple. Dans l'exemple, il y a un foo () que vous souhaitez appeler au prochain instant, vous pouvez le faire:
La copie de code est la suivante:
fonction foo () {
console.error ('foo');
}
process.NextTick (FOO);
console.error ('bar');
Exécutez le code ci-dessus et vous verrez que la sortie de "Bar" est devant "Foo". Cela vérifie l'instruction ci-dessus que Foo () exécute au moment suivant.
La copie de code est la suivante:
bar
foo
Vous pouvez également utiliser la fonction setTimeout () pour obtenir le même effet d'exécution:
La copie de code est la suivante:
setTimeout (foo, 0);
console.log ('bar');
Cependant, en termes de mécanisme de traitement interne, Process.NextTick () et SetTimeout (FN, 0) sont différents. process.NextTick () n'est pas un simple délai, il a plus de fonctionnalités.
Plus précisément, l'appel défini par Process.NextTtick () crée une nouvelle substitution. Dans la pile actuelle, vous pouvez effectuer autant d'opérations que vous le souhaitez. Mais une fois Netxtick est appelé, la fonction doit être renvoyée à la pile parent. Ensuite, le mécanisme de sondage des événements attend que de nouveaux événements soient à nouveau traités. Si NextTick est trouvé, une nouvelle pile sera créée.
Jetons un coup d'œil aux circonstances à utiliser Process.NextTick ():
Les tâches à forte intensité de l'opération CPU interdite dans plusieurs événements:
Dans l'exemple suivant, il y a un calcul (). Nous espérons que cette fonction sera exécutée aussi continuellement que possible pour effectuer des tâches à forte intensité de fonctionnement.
Mais en même temps, nous espérons également que le système ne sera pas bloqué par cette fonction et sera également en mesure de répondre et de gérer d'autres événements. Ce modèle d'application est comme un seul serveur de services Web enfileux. Ici, nous pouvons utiliser Process.NextTtick () pour interroger Compute () et la réponse d'événement normale.
La copie de code est la suivante:
var http = require ('http');
Fonction Compute () {
// effectue des calculs compliqués en continu
// ...
process.NextTick (calcul);
}
http.createServer (fonction (req, res) {
res.writeHead (200, {'Content-Type': 'Text / PLAIN'});
res.end ('Hello World');
}). écouter (5000, '127.0.0.1');
calculer();
Dans ce mode, nous n'avons pas besoin d'appeler Recursivement Calpel (). Nous avons seulement besoin d'utiliser Process.NextTick () pour définir calcul () pour exécuter au prochain point de la boucle d'événement.
Au cours de ce processus, si une nouvelle demande HTTP entre en jeu, le mécanisme de boucle d'événement traitera d'abord la nouvelle demande, puis appellera calcul ().
Au contraire, si vous mettez compute () dans un appel récursif, le système sera bloqué dans calcul () et ne pouvez pas traiter de nouvelles demandes HTTP. Vous pouvez l'essayer vous-même.
Bien sûr, nous ne pouvons pas obtenir les avantages réels de l'exécution parallèle sous plusieurs CPU via Process.NextTick (), qui est juste de simuler la même application exécutée en segments sur le CPU.
(2), console
Console {Object} utilisé pour imprimer sur stdout et stderr.see la section stdio.
La console {objet} est utilisée pour imprimer en sortie standard et sortie d'erreur standard. Voir le test suivant:
La copie de code est la suivante:
Console.log ("Hello BigBear!");
pour (var i dans la console) {
console.log (i + "" + console [i]);
}
Les résultats de sortie suivants seront obtenus:
La copie de code est la suivante:
var log = fonction () {
process.stout.write (format.apply (this, arguments) + '/ n');
}
var info = function () {
process.stout.write (format.apply (this, arguments) + '/ n');
}
var warn = function () {
writeError (format.Apply (this, arguments) + '/ n');
}
var error = function () {
writeError (format.Apply (this, arguments) + '/ n');
}
var dir = fonction (objet) {
var util = require ('util');
process.stdout.write (util.inspect (objet) + '/ n');
}
var time = fonction (label) {
Times [Label] = date.Now ();
}
var timeEnd = fonction (label) {
var durée = date.Now () - fois [label];
export.log («Undefined: nanms», étiquette, durée);
}
var trace = fonction (label) {
// TODO peut probablement faire cela mieux avec l'objet de débogage de V8 une fois que c'est
// exposé.
var err = nouvelle erreur;
err.name = 'trace';
err.message = label || '';
Error.CaptureStackTrace (err, arguments.callee);
Console.Error (err.stack);
}
var assert = fonction (expression) {
if (! expression) {
var arr = array.prototype.slice.call (arguments, 1);
require ('assert'). ok (false, format.apply (this, arr));
}
}
Grâce à ces fonctions, nous savons essentiellement ce que NodeJS a ajouté à la portée globale. En fait, les API pertinentes sur l'objet Console encapsulent uniquement le "stdout.write" sur l'objet Process et l'accrochent à l'objet global.
(3), exportations et modules.Exports
Dans NodeJS, il y a deux portées, divisées en portée globale et en portée du module
La copie de code est la suivante:
var name = 'var-name';
name = 'name';
global.name = 'global-name';
this.name = 'module-name';
console.log (global.name);
console.log (this.name);
console.log (nom);
Nous voyons que var name = 'var-name'; name = 'name'; est une variable locale définie;
global.name = 'global-name'; Définit un attribut de nom pour l'objet global.
Et this.name = 'module-name'; définit un attribut de nom pour l'objet module
Alors vérifions-le, enregistrons ce qui suit en tant que test2.js et exécutons-le
La copie de code est la suivante:
var t1 = require ('./ test1');
console.log (t1.name);
console.log (global.name);
Comme on peut le voir à partir des résultats, nous avons réussi à importer le module Test1 et avons exécuté le code TEST1 car Global.name est sorti dans Test2.
t1.name est défini dans le module Test1 via ce.name, indiquant que cela pointe vers l'objet de portée du module.
Une petite différence entre les exportations et le module.Exports
Module.exports est l'interface réelle, et les exportations ne sont qu'un outil auxiliaire. Le retour final à l'appel est Module.exports au lieu d'exportations.
Toutes les propriétés et méthodes collectées par les exportations sont affectées à Module.exports . Bien sûr, il y a une condition préalable à cela, c'est-à-dire que Module.exports本身不具备任何属性和方法。
如果, Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。
Prenez un châtaignier:
Créer un nouveau fichier bb.js
La copie de code est la suivante:
export.name = function () {
console.log («Mon nom est Big Bear!»);
};
Créer un fichier de test test.js
La copie de code est la suivante:
var bb = require ('./ bb.js');
bb.name (); // Je m'appelle Big Bear! '
Modifiez BB.JS comme suit:
La copie de code est la suivante:
module.exports = 'bigbear!' ;
export.name = function () {
console.log («Mon nom est Big Bear!»);
};
Reportez-vous à nouveau à Exécuter BB.JS
La copie de code est la suivante:
var bb = require ('./ bb.js');
bb.name (); // n'a pas de méthode «nom»
De cela, nous pouvons voir que votre module n'a pas nécessairement à retourner un "objet instivé". Votre module peut être n'importe quel objet JavaScript légal - Boolien, numéro, date, JSON, chaîne, fonction, tableau, etc.
(4), setTimeout, setInterval, process.nexttick, setImMediate
Ce qui suit est sous la forme d'un résumé
NodeJS est caractérisé par une concurrence élevée et élevée générée par des E / S asynchrones. Le moteur qui produit cette fonctionnalité est une boucle d'événements. Les événements sont classés en observateurs d'événements correspondants, tels que les observateurs inactifs, les observateurs de minuterie, les observateurs d'E / S, etc. Chaque boucle de la boucle d'événement est appelée tick. Chaque tick retire les événements des observateurs de l'événement en séquence pour le traitement.
La minuterie créée lors de l'appel setTimeout () ou setInterval () sera placée dans l'arbre rouge et noir à l'intérieur de l'observateur de la minuterie. Chaque fois que vous cochez, il vérifiera si la minuterie a dépassé le temps de synchronisation de l'arbre rouge et noir. S'il dépasse le timing, la fonction de rappel correspondante sera exécutée immédiatement. setTimeout () et setInterval () sont tous deux utilisés par les minuteries. La différence est que ce dernier est déclenché à plusieurs reprises et parce que le réglage du temps est trop court, le traitement après le déclencheur précédent sera déclenché immédiatement après la fin du déclencheur précédent.
Étant donné que la minuterie est un déclencheur de délai d'expiration, cela réduira la précision du déclencheur. Par exemple, le délai d'expiration défini avec Settimeout est de 5 secondes. Lorsque la boucle d'événement passe par une tâche dans la 4e seconde et que son temps d'exécution est de 3 secondes, la fonction de rappel Settimeout expirera pendant 2 secondes, ce qui est la raison de la réduction de la précision. Et parce que la minuterie et les déclencheurs de jugement sont sauvés à l'aide d'arbres rouges et noirs et de méthodes itératives, c'est un gaspillage de performance.
Toutes les fonctions de rappel définies à l'aide de process.NextTick () seront placées dans le tableau, et tous seront exécutés immédiatement la prochaine fois que vous cochez. Cette opération est légère et a une précision de temps élevée.
La fonction de rappel définie par SetImMediate () est également appelée sur la prochaine tique. La différence entre l'informatique et le processus.NextTick () est de deux points:
1. La priorité d'exécution de l'observateur auquel ils appartiennent est différent. Process.NextTick () appartient à l'observateur inactif, SetImMediat () appartient à l'observateur de contrôle et la priorité de l'inactivité> Vérifier.
2. La fonction de rappel définie par SETIMMEDIAD () est placée dans une liste liée, et un seul rappel de la liste liée est exécuté à chaque fois. Il s'agit de s'assurer que chaque tique peut être exécutée rapidement.
Deuxièmement, résumons
1. Comprendre la signification de l'existence d'objets globaux
2. Une petite différence entre les exportations et le module.Exports
3. Quelle est la couche sous-jacente de console construite (encapsulation de haut niveau des objets de processus)
4. La différence entre setTimeout, setInterval, process.nexttick, setimMediate
5. Deux portées dans les nodejs