Node.jsのイベントループについて
JavaScriptはシングルスレッドなので「並行処理」を行うために、「ノンブロッキングI/O」で「非同期処理」を実現しており
Node.jsはイベントループと呼ばれるモデルを採用しています。
イベントループのイベントキューにイベントが登録され、イベントハンドラを実行します。
イベントハンドラの完了した結果は、イベントキューにコールバック関数を登録することで受け取ります。
そのため、シングルスレッドでブロックするI/Oを行った場合、そのイベント完了後に次のイベントが実行されてしまう。
並行処理させるためには、ノンブロッキングI/Oを使ってイベントの完了を待たずに次のイベントハンドラを実行させます。
Node.jsはイベントを生成と処理の制御を行うので
ファイルのリード、DBへのクエリ発行、HTTPサーバがリクエストを受けた時などにイベントが生成されます。
例えばテストファイルを作って試すとわかります。
test.js
var oHttp = require('http'); var oFs = require('fs'); oHttp.createServer(function(req, res) { console.log("Start"); oFs.readFile('index.txt', function(err, content) { res.writeHead(200, { 'Content-Type':'text/html; charset=utf-8' }); res.end(content); console.log("Response"); }); console.log("End"); }).listen(8080, '127.0.0.1'); console.log('ListenStart');
読み込むファイル
<html/> <head/> <title/>index</title/> </head/> <body/> みれた? </body/> </html/>
実行
[root@dti-vps-srv34 ~]#node test.js
ブラウザで「http://127.0.0.1:8080」にアクセス。
[root@dti-vps-srv34 ~]#node test.js ListenStart Start End Response
EndがResponseより先になっています。
これはreadFile()にコールバック関数を登録しているので、非同期となり
読み込み完了した時点で関数が呼び出されているからです。
プログラムの書き方によっては非同期の部分をロックしてしまうので注意。