この記事では、Node.js イベント ループと Node.js コールバック関数について詳しく説明します。詳細については、以下を参照してください。
1. Node.js イベント ループ
Node.js は単一プロセス、単一スレッドのアプリケーションですが、イベントとコールバックによる同時実行をサポートしているため、パフォーマンスは非常に高くなります。 Node.js のすべての API は非同期であり、別個のスレッドとして実行され、非同期関数呼び出しを使用し、同時実行を処理します。基本的に、Node.js のすべてのイベント メカニズムは、デザイン パターンのオブザーバー パターンを使用して実装されます。 Node.js の単一スレッドは、イベント オブザーバーが終了するまで while(true) イベント ループに入るのと似ています。イベントが発生すると、コールバック関数が呼び出されます。
Node.js はイベント駆動型モデルを使用し、Web サーバーがリクエストを受信すると、リクエストを閉じて処理し、次の Web リクエストを処理します。リクエストが完了すると、リクエストは処理キューに戻され、キューの先頭に達すると結果がユーザーに返されます。このモデルは、Web サーバーが読み取りまたは書き込み操作を待たずに常にリクエストを受け入れるため、非常に効率的でスケーラブルです。 (これは、ノンブロッキング IO またはイベント駆動型 IO とも呼ばれます)。イベント駆動型モデルでは、イベントをリッスンし、イベントが検出されたときにコールバック関数をトリガーするメイン ループが生成されます。
イベント駆動型プロセス全体はこのように非常に簡単に実装されます。オブザーバー パターンとある程度似ており、イベントはサブジェクト (Subject) に相当し、このイベントに登録されたすべてのハンドラー関数はオブザーバー (Observer) に相当します。 Node.js には複数の組み込みイベントがあります。以下に示すように、イベント モジュールを導入して EventEmitter クラスをインスタンス化することで、イベントをバインドしてリッスンできます。 例
js を作成します。ファイルのコードは次のとおりです。
// 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var eventEmitter = new events.EventEmitter(); 以下程序绑定事件处理程序: // 绑定事件及事件的处理程序 eventEmitter.on('eventName', eventHandler); 我们可以通过程序触发事件: // 触发事件 eventEmitter.emit('eventName');
Node.js 非同期プログラミングの直接的な表現はコールバックです。非同期プログラミングはコールバックに依存しますが、コールバックを使用したからといってプログラムが非同期になるとは言えません。コールバック関数は、タスクの完了後に呼び出されます。すべてのノード API はコールバック関数をサポートしています。たとえば、他のコマンドの実行中にファイルを読み取ることができます。ファイルの読み取りが完了したら、ファイルの内容をコールバック関数のパラメーターとして返します。これにより、コードの実行中にファイル I/O 操作がブロックされたり、待機したりすることがなくなります。これにより、Node.js のパフォーマンスが大幅に向上し、多数の同時リクエストを処理できるようになります。
1. ブロック コードの例
次の内容のファイル test.txt を作成します:// 引入 events 模块 var events = require('events'); // 创建 eventEmitter 对象 var eventEmitter = new events.EventEmitter(); // 创建事件处理程序 var connectHandler = function connected() { console.log('连接成功。'); // 触发 data_received 事件 eventEmitter.emit('data_received'); } // 绑定 connection 事件处理程序 eventEmitter.on('connection', connectHandler); // 使用匿名函数绑定 data_received 事件 eventEmitter.on('data_received', function(){ console.log('数据接收成功。'); }); // 触发 connection 事件 eventEmitter.emit('connection'); console.log("程序执行完毕。");
次のコードを含む test.js ファイルを作成します:
Hello World! fs.readFileSync() fs.readFile()
2. ノンブロッキング コードの例
test.js ファイルを作成します。コードは次のとおりです:console.log('-------程序开始执行--------'); // 引入fs模块 var fs = require("fs"); //同步读取文件 var data = fs.readFileSync('test.txt','utf-8'); console.log(data.toString()); console.log('-------程序执行结束--------');
上記のプログラムでは、fs.readFile() は非同期です。ファイルを読み取るために使用される関数。ファイルの読み取り中にエラーが発生した場合、error err オブジェクトはエラー情報を出力します。エラーが発生しない場合、readFile は err オブジェクトの出力をスキップし、ファイルの内容はコールバック関数を通じて出力されます。
次に input.txt ファイルを削除します。実行結果は次のとおりです。
上記 2 つの例では、ブロック呼び出しと非ブロック呼び出しの違いがわかります。最初のインスタンスは、ファイルの読み取り後にプログラムの実行を終了します。 2 番目の例では、ファイルが読み取られるのを待つ必要がないため、ファイルの読み取りと同時に次のコードを実行できるため、プログラムのパフォーマンスが大幅に向上します。したがって、ブロッキングは順番に実行されますが、ノンブロッキングは順番に実行する必要がないため、コールバック関数のパラメータを処理する必要がある場合は、コールバック関数内に記述する必要があります。 3. fs.readFileSync と fs.readFile1. s.readFileSync
構文: fs.readFileSync(filename, [encoding])
受信パラメータ:
ファイル名: ファイルパス