Node.js и Express: как вернуть ответ после асинхронной операции

Я новичок в Node.js, поэтому я все еще обволакиваю асинхронные функции и обратные вызовы. Моя борьба теперь заключается в том, как вернуть ответ после чтения данных из файла в асинхронной операции.

Я понимаю, что отправка ответа работает так (и это работает для меня):

app.get('/search', function (req, res) {
    res.send("request received");
});

Однако теперь я хочу прочитать файл, выполнить некоторые операции над данными, а затем вернуть результаты в ответ. Если операции, которые я хотел выполнить для данных, были простыми, я мог бы сделать что-то вроде этого - выполнить их встроенный и поддерживать доступ к объекту res, поскольку он все еще находится в пределах области действия.

app.get('/search', function (req, res) {
    fs.readFile("data.txt", function(err, data) {
        result = process(data.toString());
        res.send(result);
    });
});

Однако операции с файлами, которые мне нужно выполнить, являются длинными и сложными, и я отделил их в свою собственную функцию в отдельном файле. В результате мой код выглядит примерно так:

 app.get('/search', function (req, res) {
    searcher.do_search(res.query);
    // ??? Now what ???
});

Мне нужно позвонить res.send, чтобы отправить результат. Однако я не могу назвать это непосредственно в функции выше, потому что do_search выполняется асинхронно. И я не могу назвать это в обратном вызове do_search, потому что объект res не находится в области видимости.

Может кто-нибудь помочь мне понять правильный способ справиться с этим в Node.js?

Ответ 1

Чтобы получить доступ к переменной в другой функции, если нет общей области, передайте ее как аргумент.

Вы можете просто передать res, а затем получить доступ к query и send для одной переменной внутри функции.


В целях разделения проблем вам может быть лучше передать обратный вызов.

Тогда do_search нужно знать только о выполнении запроса, а затем запустить функцию. Это делает его более общим (и, следовательно, многоразовым).

searcher.do_search(res.query, function (data) {
    res.send(...);
});

function do_search(query, callback) {
    callback(...);
}