Reputation: 1051
I'm new to Node.js, so I'm still wrapping my head around asynchronous functions and callbacks. My struggle now is how to return a response after reading data from a file in an asynchronous operation.
My understanding is that sending a response works like this (and this works for me):
app.get('/search', function (req, res) {
res.send("request received");
});
However, now I want to read a file, perform some operations on the data, and then return the results in a response. If the operations I wanted to perform on the data were simple, I could do something like this -- perform them inline, and maintain access to the res
object because it's still within scope.
app.get('/search', function (req, res) {
fs.readFile("data.txt", function(err, data) {
result = process(data.toString());
res.send(result);
});
});
However, the file operations I need to perform are long and complicated enough that I've separated them out into their own function in a separate file. As a result, my code looks more like this:
app.get('/search', function (req, res) {
searcher.do_search(res.query);
// ??? Now what ???
});
I need to call res.send
in order to send the result. However, I can't call it directly in the function above, because do_search
completes asynchronously. And I can't call it in the callback to do_search
because the res
object isn't in scope there.
Can somebody help me understand the proper way to handle this in Node.js?
Upvotes: 22
Views: 27435
Reputation: 65
The existing answers are perfectly valid, you can also use async/await keywords since ES2017. Using your own function:
app.get('/search', async(req, res, next) {
try {
const answer = await searcher.do_search(req.query);
res.send(answer);
}
catch(error) {
return next(error);
}
});
Upvotes: 4
Reputation: 943099
To access a variable in a different function, when there isn't a shared scope, pass it as an argument.
You could just pass res
and then access both query
and send
on the one variable within the function.
For the purposes of separation of concerns, you might be better off passing a callback instead.
Then do_search
only needs to know about performing a query and then running a function. That makes it more generic (and thus reusable).
searcher.do_search(res.query, function (data) {
res.send(...);
});
function do_search(query, callback) {
callback(...);
}
Upvotes: 19