海未「イベントの基礎については前回見てきましたが、今回はNode.jsの根幹をなすイベントループの仕組みを概観してみましょう」
海未「今回もまた、最初に見たWebサーバのコードを思い出してください」
1 2 3 4 5 6 7 |
var http = require("http"); http.createServer(function(req, res) { res.writeHead(200, {"Content-Type": "text/plain"}); res.end("ちゅんちゅん\n"); }).listen(25252, "127.0.0.1"); console.log("25252ポートで待ち受け中です"); |
海未「これを実行すると、プログラムは終了せずリクエストを待ち続けていました。これが、イベントループが回っている状態です」
穂乃果「ふむふむ・・・」
海未「では例えば、このようなプログラムがあったらどうでしょう」
1 2 3 |
var http = require("http"); http.createServer(function() {}); |
海未「これを実行すると、すぐにプログラムが終了してしまいますね」
ことり「えーと・・・うん、終了しちゃうね」
海未「これは、イベントループに対してハンドルの登録がされていないからです」
穂乃果「ハンドル?」
海未「ハンドルとかコールバックとか色々呼び方はあるようですが、createServer
の引数にしているような、イベントを処理するための関数です」
ことり「前回出てきたイベントリスナー・・・みたいなものかな?」
海未「言葉の使い分け、正直私にもよくわかりません・・・」
海未「とにかく、createServer
でできたサーバに対してlisten
を呼び出すと、イベントループにハンドルが登録されます。この状態になると、イベントループは回り続けます」
穂乃果「何かやることがあるうちは動いてるんだね」
海未「はい。ですから、ハンドルを削除するAPIを使うと、そこでイベントループは止まります」
海未「ハンドル(handle)の他に、リクエスト(req)があります。同じようにイベントを処理する関数ですが、入出力が発生しているときだけイベントループを回すものです」
ことり「処理が終わったら勝手に消えちゃう感じかな」
海未「イベントループが具体的に何をしているかを見てみましょう」
setTimeout
のコールバックprocess.nextTick
のコールバック- I/O処理
setImmediate
のコールバック
海未「この4ステップがwhile
で繰り返されていると考えると大まかには合っていると思います」
穂乃果「知らない単語が・・・」
海未「setTimeout
、process.nextTick
、setImmediate
はいずれもイベントループにハンドルを追加するものです」
ことり「違うのは実行される順番?」
海未「setTimeout
に関しては、指定した一定時間後に登録される動きになります。他の2つは次のループで実行されるので、そこが違いですね」
海未「ともかく、process.nextTick
などでプログラム上で追加したり、HTTPリクエストのように自然発生したハンドルやリクエストは、イベントループのキューに追加されていきます」
ことり「そういえば、前にそんな話あったね」
海未「そうです。そして、そのキューからイベントを取り出して、上記のように処理していくのです」
海未「どうやらユーザプログラムは、上記の2からスタートするということのようです。例えばこんなコードを書いたとすると」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
setTimeout(function() { console.log("ファイトだよっ!"); }, 0); setImmediate(function() { console.log("ちゅんちゅん"); }); process.nextTick(function() { console.log("ラブアローシュート!"); }); process.nextTick(function() { console.log("にっこにっこにー☆"); }); |
ラブアローシュート!
にっこにっこにー☆
ファイトだよっ!
ちゅんちゅん
海未「pcocess.nextTick
→setImmediate
→setTimeout
の順に実行されていますね」
穂乃果「うーむ・・・」
海未「このあたりは、今は厳密に理解する必要はありません。パフォーマンスを意識する段になってから深く調べればよいでしょう」
海未「イベントループの基礎はこんなところです。次回はストリームやファイルの扱いについて見てみましょう」