ホームページ  >  記事  >  ウェブフロントエンド  >  Nodejs の学習メモ グローバル オブジェクト global object_node.js

Nodejs の学習メモ グローバル オブジェクト global object_node.js

WBOY
WBOYオリジナル
2016-05-16 16:20:441062ブラウズ

1、分析を開始します

前の章では、NodeJS の基本的な理論的知識を学びました。これらの理論的知識を理解することが重要です。次の章では、公式ドキュメントに従って、その中のさまざまなモジュールを徐々に学習していきます。この記事の主人公が登壇するのは、グローバル

公式の定義を見てみましょう:

グローバル オブジェクトグローバル オブジェクトこれらのオブジェクトの一部は、実際にはグローバル スコープ内ではなく、モジュール スコープ内にあります。

これらのオブジェクトはすべてのモジュールで使用できます。実際、一部のオブジェクトはグローバル スコープ内になく、そのモジュール スコープ内にあります。これらは識別されます。

ブラウザでは、トップレベルのスコープはグローバル スコープです。つまり、ブラウザでグローバル スコープ内にいる場合は、var somethingグローバル変数が定義されます。

Node ではこれは異なります。トップレベルのスコープはグローバル スコープではありません。var somethingNode モジュール内はそのモジュールに対してローカルになります。

ブラウザでは、グローバル オブジェクトの概念は誰もがよく知っているはずです。ブラウザの最上位スコープはグローバル スコープです。つまり、「var」を使用してグローバル スコープで変数を定義すると、この変数は次のようになります。グローバル スコープとして定義されます。

ただし、NodeJS では異なります。最上位のスコープはグローバル スコープではありません。モジュール内の変数を定義するには、この変数のみを使用します。

NodeJS では、モジュールで定義された変数、関数、またはメソッドはそのモジュール内でのみ使用できますが、exports オブジェクトを使用してモジュールの外に渡すことができます。

ただし、Node.js には依然としてグローバル スコープが存在します。つまり、モジュールをロードせずに使用できるいくつかの変数、関数、またはクラスを定義できます。

同時に、いくつかのグローバル メソッドとグローバル クラスも事前定義されています。Global オブジェクトは、NodeJS のグローバル名前空間です。グローバル変数、関数、またはオブジェクトは、オブジェクトの属性値です。

REPL 実行環境では、次の図に示すように、次のステートメントを通じて Global オブジェクトの詳細を観察できます。

以下では、Global オブジェクトに実装されている関連する属性値オブジェクトについて 1 つずつ説明します。

(1)、プロセス

Process {Object} プロセス オブジェクト。プロセス オブジェクトのセクションを参照してください。

プロセス {オブジェクト} これはプロセス オブジェクトです。 詳細については後続の章で説明しますが、ここでは API を取り出して説明したいと思います。

Process.nextTick(コールバック)

イベント ループの次のループで、このコールバックを呼び出します。これは setTimeout(fn, 0) の単純なエイリアスではなく、通常は他の I/O イベントが発生する前に実行される方が効率的です。例外については、以下の process.maxTickDepth を参照してください。


イベント ループの次の反復でコールバック コールバック関数を呼び出します。これは setTimeout(fn, 0) 関数の単純なエイリアスではなく、はるかに効率的です。

この関数は、I/O の前にコールバック関数を呼び出すことができます。オブジェクトの作成後、I/O 操作が発生する前にいくつかの操作を実行する場合、この関数は非常に重要です。

Node.js の process.nextTick() の使い方を理解していない人が多いです。 process.nextTick() とは何か、そしてその使い方を見てみましょう。

Node.js はシステム IO に加えて、イベント ポーリング プロセス中に同時に処理されるイベントは 1 つだけです。イベント ポーリングは、各時点で 1 つのイベントのみを処理する大きなキューと考えることができます。

コンピューターに複数の CPU コアが搭載されている場合でも、複数のイベントを同時に並行して処理することはできません。ただし、この特性により、node.js は I/O タイプのアプリケーションの処理には適していますが、CPU ベースのコンピューティング アプリケーションには適していません。

すべての I/O タイプのアプリケーションでは、入力と出力ごとにコールバック関数を定義するだけで、イベント ポーリングの処理キューに自動的に追加されます。

I/O 操作が完了すると、このコールバック関数がトリガーされます。その後、システムは他のリクエストの処理を続行します。

この処理モードでは、process.nextTick() はアクションを定義し、このアクションを次のイベント ポーリング時点で実行させることを意味します。例を見てみましょう。この例には foo() がありますが、これを次の時点で呼び出したい場合は、次のようにすることができます。

コードをコピーします コードは次のとおりです:
関数 foo() {
console.error('foo');
}

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

上記のコードを実行すると、以下のターミナルに出力される情報から、「bar」の出力が「foo」の前にあることがわかります。これにより、上記のステートメントが検証され、次の時点で foo() が実行されます。

コードをコピーします コードは次のとおりです:

バー
ふー

setTimeout() 関数を使用して、一見同じ実行効果を実現することもできます。

コードをコピーします コードは次のとおりです:

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

しかし、内部処理メカニズムの点では、process.nextTick() と setTimeout(fn, 0) は異なります。 process.nextTick() は単純な遅延ではなく、より多くの 機能 を備えています。

より正確には、process.nextTick() で定義された呼び出しによって新しいサブスタックが作成されます。現在のスタックに対して任意の数の操作を実行できます。ただし、netxTick が呼び出されると、関数は親スタックに戻る必要があります。その後、イベント ポーリング メカニズムは、新しいイベントが再度処理されるのを待ちます。nextTick への呼び出しが見つかると、新しいスタックが作成されます。

process.nextTick() をいつ使用するかを見てみましょう:

複数のイベントにわたる CPU 負荷の高いタスクを相互実行します:

次の例には、compute() があり、計算負荷の高いタスクを実行するために、この関数ができるだけ継続的に実行されることが望まれます。

しかし同時に、システムがこの機能によってブロックされないことを望みますが、他のイベントに応答して処理できる必要もあります。このアプリケーション モデルは、シングル スレッドの Web サービス サーバーに似ています。ここでは、 process.nextTick() を使用して、compute() と通常のイベント応答を相互実行できます。

コードをコピーします コードは次のとおりです:

var http = require('http');
関数 compute() {
// 複雑な計算を継続的に実行します
// ...
process.nextTick(compute);
}
http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World');
}).listen(5000, '127.0.0.1');
計算();

このモードでは、compute() を再帰的に呼び出す必要はありません。イベント ループで process.nextTick() を使用して、次の時点で実行される compute() を定義するだけです。

このプロセス中に、新しい http リクエストが到着すると、イベント ループ メカニズムは最初に新しいリクエストを処理し、次に compute() を呼び出します。

逆に、再帰呼び出しに compute() を入れると、システムは常に compute() でブロックされ、新しい http リクエストを処理できなくなります。自分で試してみることもできます。

もちろん、process.nextTick() では、複数の CPU での並列実行の本当の利点を得ることができません。これは、CPU 上での同じアプリケーションのセグメント化された実行をシミュレートするだけです。

(2)、コンソール

console {Object} stdout と stderr への出力に使用されます。stdio セクションを参照してください。

コンソール {object} は、標準出力とエラー出力に出力するために使用されます。以下のテストを参照してください:

コードをコピーします コードは次のとおりです:

console.log("こんにちは Bigbear!") ;
for(コンソールの変数 i){
console.log(i " " console[i]) ;
}

次の出力が得られます:

コードをコピー コードは次のとおりです:

var log = function () {
  process.stdout.write(format.apply(this, argument) 'n');
}
var info = function () {
  process.stdout.write(format.apply(this, argument) 'n');
}
var warn = function () {
  writeError(format.apply(this, argument) 'n');
}
var error = function () {
  writeError(format.apply(this, argument) 'n');
}
var dir = 関数 (オブジェクト) {
  var util = require('util');
  process.stdout.write(util.inspect(object) 'n');
}
var time = 関数 (ラベル) {
  回[ラベル] = Date.now();
}
var timeEnd = 関数 (ラベル) {
  var period = Date.now() - 回[ラベル];
  exports.log('未定義: NaNms', ラベル, 期間);
}
vartrace = 関数 (ラベル) {
  // TODO は、
になったら、V8 のデバッグ オブジェクトを使用してこれをより適切に実行できる可能性があります。   // 公開されます。
  var err = 新しいエラー;
  err.name = 'トレース';
  err.message = ラベル || '';
  Error.captureStackTrace(err, argument.callee);
  console.error(err.stack);
}
varassert = 関数 (式) {
  if (!式) {
    var arr = Array.prototype.slice.call(arguments, 1);
    require('assert').ok(false, format.apply(this, arr));
  }
}

これらの関数を通じて、私たちは全局作用領域にある基本的な知識 NodeJS にいくつかのコンテンツを追加しました。その内容は、コンソール オブジェクト上の関連 API のみです。プロセス オブジェクト上の "stdout.write" が実行され、より高いレベルのパッケージが全局に到達しました。

(3)、exports与module.exports

NodeJS には 2 つの作用領域があり、全局作用領域と模造作用領域に分けられます

复制代 代码如下:

var name = 'var-name';
名前 = '名前';
global.name='グローバル名';
this.name = 'モジュール名';
console.log(global.name);
console.log(this.name);
console.log(名前);

我们看到var name = 'var-name';name = 'name'; 所定の局部变量です;

、global.name='global-name'; は全局对オブジェクト定义一名属性です、

したがって this.name = 'module-name';是模块对オブジェクト定义了一名属性

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

复制代 代码如下:

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

結果がわかりました、私たちは 了test1 モジュールの入力に成功し、test1 の代コードを実行しました、そのため test2 中に 了global.name が出力されました、

しかし、t1.name は test1 モジュール内で this.name によって決定されており、この方向がモジュール作用フィールドのオブジェクトであることを示しています。

exports与module.exportsの一点区别

     は真のインターフェイスであり、エクスポートは単なる補助ツールではありません。最終的に返されるのは、エクスポートではなく Module.exports です。 Module.exports すべてのエクスポートが収集されたプロパティとメソッド、すべてが

で完了しました。当然、これには前提条件があり、

Module.exportsModule.exports本身不具备任何属性和方法

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

新建一文件 bb.js

exports.name = function() {
    console.log('私の名前は大熊です!') ;
} ;


创建一测试文件 test.js

var bb= require('./bb.js');
bb.name(); // '私の名前は大熊です!'


修正bb.js如下:

复制代码代码如下:

module.exports = 'ビッグベア!' ;
exports.name = function() {
console.log('私の名前はビッグベアです!') ;
} ;

bb.js を参照して再度実行

コードをコピーします コードは次のとおりです:

var bb= require('./bb.js');
bb.name(); // メソッド 'name'
がありません

モジュールが必ずしも「インスタンス化されたオブジェクト」を返す必要がないことがわかります。モジュールには、ブール値、数値、日付、JSON、文字列、関数、配列などの正当な JavaScript オブジェクトを使用できます。

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

以下は概要の形式で表示されます

Nodejs は、非同期 I/O によって生成されるイベント駆動型の高い同時実行性を特徴としています。この機能を生成するエンジンは、イベント オブザーバー (アイドル オブザーバー、タイマー オブザーバーなど) に分類されます。 ○オブザーバーなど イベントループの各サイクルをTickと呼び、各Tickはイベントオブザーバーからイベントを順番に取り出して処理します。

setTimeout() または setInterval() を呼び出したときに作成されたタイマーは、タイマー オブザーバー内の赤黒ツリーに配置され、タイマーがタイムアウトを超えたかどうかを赤黒ツリーから確認します。 . を超えると、対応するコールバック関数がすぐに実行されます。 setTimeout() と setInterval() はどちらもタイマーとして使用されます。違いは、後者は繰り返しトリガーされることと、時間が短すぎるため、前のトリガーの後の処理が完了した直後にトリガーされることです。

タイマーはタイムアウトによってトリガーされるため、たとえば、イベント ループが 4 秒目にタスクをループし、その実行時間が 3 秒の場合、トリガーの精度が低下します。 , その後、setTimeout コールバック関数は 2 秒で期限切れになり、これが精度の低下の原因です。また、タイマーの保存とトリガーの決定に赤黒ツリーと反復メソッドが使用されるため、パフォーマンスが無駄になります。

process.nextTick() を使用して設定されたすべてのコールバック関数は配列に配置され、すべてが次の Tick ですぐに実行されます。この操作は比較的軽量で、時間精度が高くなります。

setImmediate() で設定されたコールバック関数は次の Tick でも呼び出されます。 process.nextTick() との違いは次の 2 点です。

1. 属するオブザーバーは異なる優先度で実行されます。 process.nextTick() はアイドルオブザーバーに属し、setImmediate() はチェックオブザーバーに属し、アイドル > チェックの優先度になります。

2. setImmediate() で設定されたコールバック関数はリンク リストに配置され、各 Tick はリンク リスト内の 1 つのコールバックのみを実行します。これは、各ティックを迅速に実行できるようにするためです。

2 番目に要約します

1. Global オブジェクトの存在の意味を理解する

2.exports と module.exports のちょっとした違い

3. コンソールの基礎となる構造は何ですか (プロセス オブジェクトの高レベルのカプセル化)

4. setTimeout、setInterval、process.nextTick、setImmediate の違い

5. NodeJS の 2 種類のスコープ


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。