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?
The A in Ajax stands for asynchronous. That means sending the request (or rather receiving the response) is taken out of the normal execution flow. In your example, $. ajax returns immediately and the next statement, return result; , is executed before the function you passed as success callback was even called.
The best way to handle asynchronous API responses is to access the corresponding API resource (Rate or Transaction) one or multiple times after object creation. As soon as a carrier has returned a rate or label, it will be accessible in the corresponding Shippo API resource.
js ? We have to call the async function from another function which can be asynchronous or synchronous (We can pass the array or choose to declare the array in the async function itself) and then return the array from the async function.
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(...);
}
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);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With