Maison > interface Web > js tutoriel > le corps du texte

Notes d'étude Nodejs Objets globaux global object_node.js

WBOY
Libérer: 2016-05-16 16:20:44
original
1065 Les gens l'ont consulté

1, analyse d'ouverture

Dans le dernier chapitre, nous avons appris les connaissances théoriques de base de NodeJS. Il est crucial de comprendre ces connaissances théoriques. Dans les chapitres suivants, nous apprendrons progressivement les différents modules selon les documents officiels. pour que le protagoniste de cet article monte sur scène, Global

Regardons la définition officielle :

Objets globauxObjets globauxCes 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, mais sont dans la portée de son module ------ceux-ci seront identifiés.

Dans les navigateurs, la portée de niveau supérieur est la portée globale. Cela signifie que dans les navigateurs, si vous êtes dans la portée globalevar somethingdéfinira une variable globale.

Dans Node, c'est différent. La portée de niveau supérieur n'est pas la portée globale ;var somethingà l'intérieur d'un module Node sera local à ce module.

Je pense que tout le monde devrait être familier avec le concept d'objets globaux. Dans le navigateur, la portée de niveau le plus élevé est Global Scope, ce qui signifie que si vous utilisez "var" pour définir une variable dans Global Scope, cette variable sera défini comme portée globale.

Mais c'est différent dans NodeJS. La portée de niveau le plus élevé n'est pas la portée globale. Utilisez "var" pour définir une variable dans un module. Cette variable est uniquement dans la portée de ce module.

Dans NodeJS, les variables, fonctions ou méthodes définies dans un module ne sont disponibles que dans ce module, mais elles peuvent être transmises en dehors du module via l'utilisation de l'objet exports.

Cependant, dans Node.js, il existe toujours une portée globale, c'est-à-dire que vous pouvez définir certaines variables, fonctions ou classes qui peuvent être utilisées sans charger de modules.

En même temps, certaines méthodes globales et classes globales sont également prédéfinies. L'objet Global est l'espace de noms global dans NodeJS. Toute variable, fonction ou objet global est une valeur d'attribut de l'objet.

Dans l'environnement d'exécution REPL, vous pouvez observer les détails de l'objet Global via l'instruction suivante, comme le montre la figure ci-dessous :

Je parlerai un par un des objets de valeur d'attribut associés montés sur l'objet Global ci-dessous.

(1), Processus

Processus {Object} L'objet de processus. Voir la section Objet de processus.

Processus {object} Il s'agit d'un objet de processus. J'entrerai dans les détails dans les chapitres suivants, mais ici je souhaite sortir une API pour en parler.

Process.nextTick(rappel)

Lors de la boucle suivante autour de la boucle d'événements, appelez ce rappel. Ce n'est pas un simple alias pour setTimeout(fn, 0), il est beaucoup plus efficace, il s'exécute généralement avant le déclenchement de tout autre événement d'E/S, mais il y en a. exceptions Voir process.maxTickDepth ci-dessous.

Appelez la fonction de rappel callback lors de la prochaine itération de la boucle d'événements. Il ne s’agit pas d’un simple alias pour la fonction setTimeout(fn, 0), car elle est beaucoup plus efficace.

Cette fonction peut appeler notre fonction de rappel avant toute E/S. Cette fonction est très importante pour vous si vous souhaitez effectuer certaines opérations après la création de l'objet mais avant que l'opération d'E/S ne se produise.

De nombreuses personnes ne comprennent pas l'utilisation de process.nextTick() dans Node.js. Voyons ce qu'est process.nextTick() et comment l'utiliser.

Node.js est monothread En plus des IO système, lors de son processus d'interrogation d'événements, un seul événement sera traité en même temps. Vous pouvez considérer l’interrogation d’événements comme une grande file d’attente, à chaque instant, le système ne traitera qu’un seul événement.

Même si votre ordinateur dispose de plusieurs cœurs de processeur, vous ne pouvez pas traiter plusieurs événements en parallèle en même temps. Mais c’est cette caractéristique qui rend node.js adapté au traitement des applications de type E/S, mais pas aux applications informatiques basées sur CPU.

Dans chaque application de type 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 des interrogations d'événements.

Lorsque l'opération d'E/S est terminée, cette fonction de rappel sera déclenchée. Le système poursuivra ensuite le traitement d'autres demandes.

 

Dans ce mode de traitement, process.nextTick() signifie définir une action et laisser cette action être exécutée au prochain moment d'interrogation d'événement. Regardons un exemple. Il y a un foo() dans l'exemple. Si vous souhaitez l'appeler au moment suivant, vous pouvez faire ceci :

.

Copier le code Le code est le suivant :

fonction foo() {
​ console.error('foo');
>

process.nextTick(foo);
console.error('bar');

Exécutez le code ci-dessus, et vous verrez d'après les informations imprimées dans le terminal ci-dessous que la sortie de "bar" est devant "foo". Cela vérifie l'instruction ci-dessus, foo() est exécuté au moment suivant.

Copier le code Le code est le suivant :

bar
foo

Vous pouvez également utiliser la fonction setTimeout() pour obtenir apparemment le même effet d'exécution :

Copier le code Le code est le suivant :

setTimeout(foo, 0);
console.log('bar');

Mais en termes de mécanisme de traitement interne, process.nextTick() et setTimeout(fn, 0) sont différents. process.nextTick() n'est pas un simple retard, il a plus de fonctionnalités .

Pour être plus précis, l'appel défini par process.nextTick() crée une nouvelle sous-pile. Vous pouvez effectuer n'importe quel nombre d'opérations sur la pile actuelle. Mais une fois netxTick appelé, la fonction doit revenir à la pile parent. Ensuite, le mécanisme d'interrogation des événements attend que de nouveaux événements soient à nouveau traités. Si un appel à nextTick est trouvé, une nouvelle pile sera créée.

Voyons quand utiliser process.nextTick() :

Exécution croisée de tâches gourmandes en CPU sur plusieurs événements :

Dans l'exemple suivant, il y a un calculate(). Nous espérons que cette fonction sera exécutée aussi continuellement que possible pour effectuer certaines tâches gourmandes en calcul.

Mais en même temps, nous espérons également que le système ne sera pas bloqué par cette fonction, mais qu'il devra également être capable de répondre et de gérer d'autres événements. Ce modèle d'application est comme un serveur de service Web monothread. Ici, nous pouvons utiliser process.nextTick() pour exécuter de manière croisée Compute() et la réponse normale aux événements.

Copier le code Le code est le suivant :

var http = require('http');
fonction calculer() {
// effectue des calculs compliqués en continu
​​// ...
​​process.nextTick(calcul);
>
http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Bonjour tout le monde');
}).écouter(5000, '127.0.0.1');
calculer();

Dans ce mode, nous n'avons pas besoin d'appelercompute() de manière récursive. Nous avons seulement besoin d'utiliser process.nextTick() dans la boucle d'événements pour définircompute() à exécuter au moment suivant.

Au cours de ce processus, si une nouvelle requête http arrive, le mécanisme de boucle d'événements traitera d'abord la nouvelle requête, puis appellera computing().

Au contraire, si vous mettez computation() dans un appel récursif, le système sera toujours bloqué dans calculate() et ne pourra pas gérer les nouvelles requêtes http. Vous pouvez l'essayer vous-même.

Bien entendu, nous ne pouvons pas obtenir les réels avantages de l'exécution parallèle sous plusieurs CPU via process.nextTick(). Cela simule uniquement l'exécution segmentée de la même application sur le CPU.

 (2),Console

 console {Object} Utilisé pour imprimer sur stdout et stderr.Voir la section stdio.

La console {object} est utilisée pour imprimer sur la sortie standard et la sortie d'erreur. Voir le test ci-dessous :

 

Copier le code Le code est le suivant :

console.log("Bonjour Bigbear!") ;
pour(var i dans la console){
console.log(i " " console[i]) ;
>

Vous obtiendrez le résultat suivant :

Copier le code Le code est le suivant :

var log = fonction () {
  process.stdout.write(format.apply(this, arguments) 'n');
>
var info = fonction () {
  process.stdout.write(format.apply(this, arguments) 'n');
>
var warn = fonction () {
  writeError(format.apply(this, arguments) 'n');
>
var erreur = fonction () {
  writeError(format.apply(this, arguments) 'n');
>
var dir = fonction (objet) {
  var util = require('util');
  process.stdout.write(util.inspect(object) 'n');
>
var time = fonction (étiquette) {
  times[label] = Date.now();
>
var timeEnd = function (étiquette) {
  var durée = Date.now() - times[label];
  exports.log('undefined: NaNms', label, durée);
>
var trace = fonction (étiquette) {
  // TODO peut probablement faire mieux avec l'objet de débogage de V8 une fois que c'est le cas
  // exposé.
  var err = nouvelle erreur ;
  err.name = 'Trace';
  err.message = étiquette || '';
  Error.captureStackTrace(err, arguments.callee);
  console.error(err.stack);
>
var assert = fonction (expression) {
  si (!expression) {
    var arr = Array.prototype.slice.call(arguments, 1);
    require('assert').ok(false, format.apply(this, arr));
  >
>

  通过这些函数,我们基本上知道NodeJS在全局作用域添加了些什么内容,其实Console对象上的Le processus api est basé sur "stdout.write"对象上。

 (3),exports与module.exports

   在NodeJS中,有两种作用域,分为全局作用域和模块作用域  

复制代码 代码如下 :

var nom = 'var-name';
nom = 'nom';
global.name='nom-global';
this.name = 'nom-module';
console.log(global.name);
console.log(this.name);
console.log(nom);

  我们看到var name = 'var-name';name = 'name'; 是定义的局部变量;

  而global.name='global-name';是为 全局对象定义一个name 属性,

  而 this.name = 'module-name';是为模块对象定义了一个name 属性

  那么我们来验证一下,将下面保存成test2.js,运行

复制代码 代码如下 :

var t1 = require('./test1'); 
console.log(t1.nom); 
console.log(global.name);

  从结果可以看出,我们成功导入 了test1 模块,并运行了 test1的代码,因为在test2 中 输出 了global.name,

  而 t1.name 则是 test1 模块中通过this.name 定义的,说明this 指向 的是 模块作用域对象。

  exports与module.exports的一点区别

    Module.exports而不是exports。 Module.exports

    所有的exports收集到的属性和方法,都赋值给了

。当然,这有个前提,就是Module.exportsModule.exports本身不具备任何属性和方法

    如果,Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。

  举个栗子:

    新建一个文件 bb.js

复制代码 代码如下 :
exports.name = function() {
    console.log('Je m'appelle 大熊 !') ;
} ;

    创建一个测试文件 test.js

  

复制代码 代码如下 :
var bb= require('./bb.js');
bb.name(); // 'Je m'appelle 大熊 !'

    修改bb.js如下:

复制代码 代码如下 :

module.exports = 'BigBear!' ;
exports.name = function() {
console.log('Je m'appelle Gros Ours !') ;
} ;

Référencez et exécutez à nouveau bb.js

Copier le code Le code est le suivant :

var bb= require('./bb.js');
bb.name(); // n'a pas de méthode 'name'

On voit que votre module ne doit pas forcément renvoyer un "objet instancié". Votre module peut être n'importe quel objet JavaScript légal : booléen, nombre, date, JSON, chaîne, fonction, tableau, etc.

(4), setTimeout, setInterval, process.nextTick, setImmediate

Ce qui suit apparaît sous forme de résumé

Nodejs se caractérise par une concurrence élevée basée sur les événements générée par des E/S asynchrones. Le moteur qui produit cette fonctionnalité est la boucle d'événements. Les événements sont classés en observateurs d'événements correspondants, tels que les observateurs inactifs et les observateurs de minuterie, I/. O observateurs, etc. Chaque cycle de la boucle d'événements est appelé un Tick. Chaque Tick extrait les événements de l'observateur d'événements dans l'ordre et les traite.

Le timer créé lors de l'appel de setTimeout() ou setInterval() sera placé dans l'arbre rouge-noir à l'intérieur de l'observateur du timer. Chaque fois qu'il cochera, il vérifiera si le timer a dépassé le délai d'attente de l'arbre rouge-noir. , s'il dépasse, la fonction de rappel correspondante sera exécutée immédiatement. setTimeout() et setInterval() sont utilisés comme minuteries. La différence entre eux est que ce dernier est déclenché à plusieurs reprises et que, comme le temps est trop court, le traitement après le déclenchement précédent sera déclenché immédiatement après la fin du traitement.

Étant donné que le timer est déclenché par un timeout, cela entraînera une précision de déclenchement réduite. Par exemple, le timeout défini avec setTimeout est de 5 secondes lorsque la boucle d'événement parcourt une tâche à la 4ème seconde et que son temps d'exécution est de 3 secondes. , Ensuite, la fonction de rappel setTimeout expirera dans 2 secondes, ce qui explique la précision réduite. Et comme l’arborescence rouge-noir et les méthodes d’itération sont utilisées pour enregistrer les minuteries et déterminer les déclencheurs, il s’agit d’un gaspillage de performances.

Toutes les fonctions de rappel définies à l'aide de process.nextTick() seront placées dans le tableau et toutes seront exécutées immédiatement au prochain tick. Cette opération est relativement légère et a une précision temporelle élevée.

La fonction de rappel définie par setImmediate() est également appelée au prochain Tick. La différence entre elle et process.nextTick() réside en deux points :

 1. Les observateurs auxquels ils appartiennent sont exécutés avec des priorités différentes. process.nextTick() appartient à l'observateur inactif, setImmediate() appartient à l'observateur de contrôle et la priorité de ralenti > check.

2. La fonction de rappel définie par setImmediate() est placée dans une liste chaînée. Chaque Tick n'exécute qu'un seul rappel dans la liste chaînée. Ceci permet de garantir que chaque tick peut être exécuté rapidement.

Deuxièmement, résumez

1. Comprendre le sens de l'existence des objets Global

2. Une petite différence entre exports et module.exports

3. Quelle est la structure sous-jacente de la console (encapsulation de haut niveau de l'objet Process)

4. La différence entre setTimeout, setInterval, process.nextTick et setImmediate

5. Deux types de scopes dans NodeJS

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal