Как работает цикл обработки событий Node.js?

Поиграв с 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) Для одновременного выполнения запросов драйвер db должен иметь какой-то пул потоков / соединений, верно?

2) В рамках одного запроса: Что происходит после отправки двух запросов? renderView нельзя вызвать, потому что запросы еще не вернулись. Как нам дождаться возврата запросов? Должен ли он перед продолжением вести подсчет ожидающих выполнения обратных вызовов? Моя основная мысль была:

onRequest -> запустить асинхронный код -> дождаться обратных вызовов -> построить ответ. Ожидание в этом случае было бы блокирующим, поэтому вам фактически нужно было бы создавать поток для каждого onRequest. Как выполняется «ожидание выполнения обратных вызовов перед построением ответа»?

3) Как драйвер db сообщает циклу событий о том, что это выполнено, и о том, что для него необходимо вызвать обратный вызов с результатами запроса?

4) Как цикл событий выполняет обратный вызов внутри анонимной функции, которую мы создали с помощью события onRequest? Здесь возникает концепция закрытия, когда контекст «сохраняется» в функции обратного вызова?

4) Теперь, когда у нас есть результаты базы данных, как нам продолжить выполнение renderView / res.write / res. end частей?

9
задан Justin Case 20 July 2011 в 20:56
поделиться