После игры с Node.js и чтения об асинхронном вводе-выводе и вечернем программировании много У меня остались некоторые знаки вопроса.
Рассмотрим следующий (псевдо) код:
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) Для одновременного выполнения запросов у драйвера БД должен быть какой-то пул потоков / соединений, верно?
2) В рамках одного запроса: что происходит после отправки двух запросов? renderView не может быть вызван, потому что запросы еще не возвращены. Как мы ждем возвращения запросов? Должен ли он вести подсчет обратных вызовов, ожидающих запуска перед продолжением? Основная мысль, которая у меня была:
onRequest -> запустить асинхронный код -> дождаться обратных вызовов -> создать ответ. Ожидание в этом случае будет блокировать, поэтому вам нужно будет порождать поток для каждого onRequest. Как выполняется «ожидание выполнения обратных вызовов перед построением ответа»?
3) Как драйвер БД информирует цикл обработки событий о том, что он завершен, и обратный вызов, который у него есть, должен вызываться с результатами запроса?
4) Как цикл обработки событий выполняет обратный вызов внутри анонимной функции, которую мы создали с помощью события onRequest? В этом ли заключается концепция замыкания, когда контекст «сохраняется» в функции обратного вызова?
4) Теперь, когда у нас есть результаты в БД, как мы продолжим выполнение renderView/res.write/res.end
частей?