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(...);
}