Node.jsで遊んで、非同期I / Oとイベントプログラミングについてたくさん読んだ後、疑問符がいくつか残っています。
次の(擬似)コードについて考えてみます。
var http = require('http');
function onRequest(request, response)
{
// some non-blocking db query
query('SELECT name FROM users WHERE key=req.params['key']', function (err, results, fields) {
if (err) {
throw err;
}
username = results[0];
});
// some non-blocking db query
query('SELECT name FROM events WHERE key=req.params['key']', function (err, results, fields) {
if (err) {
throw err;
}
event_name = results[0];
});
var body = renderView(username, event_name, template);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(body);
res.end();
};
http.createServer(onRequest).listen(8888);
// request A: http://127.0.0.1:1337/?key=A
// request B: http://127.0.0.1:1337/?key=B
(私は思う)イベントループの基本を理解している。libevを使用すると、Node.jsは一連のファイル記述子をポーリング(epoll / kqueue / ...)して、イベントがトリガーされたかどうか(新しい接続、書き込み可能、データが利用可能など)を確認するイベントループを作成します。新しいリクエストがある場合、イベントループはcreateServerに渡された無名関数を呼び出します。私が理解していないのは、その後に何が起こるかです。
1)クエリを同時に実行するには、dbドライバーに何らかのスレッド/接続プールが必要です。
2)1つのリクエストの範囲内:2つのクエリを送信するとどうなりますか?クエリがまだ返されていないため、renderViewを呼び出すことはできません。クエリが返されるのをどのように待ちますか?続行する前に、発生するまで保留中のコールバックのカウントを保持する必要がありますか?私が持っていた基本的な考えは次のとおりでした。
onRequest->非同期コードの実行->コールバックの待機->応答の作成。この場合の待機はブロックされるため、onRequestごとにスレッドを効果的に生成する必要があります。「応答を作成する前にコールバックが実行されるのを待つ」はどのように行われますか?
3)dbドライバーは、イベントループにそれが完了したことをどのように通知し、クエリ結果でコールバックを呼び出す必要がありますか?
4)イベントループは、onRequestイベントで作成した無名関数内でどのようにコールバックを実行しますか?これは、コールバック関数でコンテキストが「保存」されるクロージャの概念が登場する場所ですか?
4)dbの結果が得られたので、どのようにしてrenderView/res.write/res.end
パーツの実行を継続しますか?