I want to wait for the getAllData function to be finished, but that does not work.
let _partnerToken;
async function getAllData(dealerId,id){
let partnerToken;
var options = {
'method': 'GET',
'url': _url '/' dealerId,
};
request.get(options, async function (error, response) {
if (error) throw new Error(error);
partnerToken = response.body.slice(17,-2);
await getCarData(partnerToken,id);
await getCarImages(partnerToken, id);
_partnerToken = partnerToken;
})
}
Here the post request where I want to call this function and send a response when the data is all loaded and the function is finished.
app.post('/api/urlData', async function(req,res){
const str = CircularJSON.stringify(req);
await getAllData(req.body.dealerId, req.body.vin);
res.send(req)
});
The problem is that it does the response immediately, so there is no data for the frontend. My goal is to send a signal with the response to my frontend, that all the data has loaded and can then be displayed.
CodePudding user response:
Solution
I started working with Promises and now the the responds waits for the functions to be finished.
Here is one of the new methods:
async function getCarData(partner, id) {
const options = {
url: url '/?partnertoken=' partner '&fahrzeug_id=' id,
headers: {
'x-api-key': key
}
};
return new Promise(function (resolve, reject){
request.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
let res = JSON.parse(body);
resolve(res.data[0]);
}else
reject(error);
});
})
}
app.post('/api/urlData', async function (req, res) {
let vin = req.body.vin;
let dealerId = req.body.dealerId;
const str = CircularJSON.stringify(req);
_partnerToken = await getPartnerToken(dealerId);
_data = await getCarData(_partnerToken,vin);
_dataImage = await getCarImages(_partnerToken,vin);
res.send(str)
});
I resturctured it so that every of the three methods returns a Promise.
CodePudding user response:
async
functions always must return a Promise
. If you don't return a Promise
, the runtime implicitly creates and returns one resolving to your return value (in your case undefined
).
The reason why the call to api/urlData
happens immediately without waiting for the other requests to be completed in getAllData()
is that you're calling request.get(...)
passing a callback function. This function works asynchronously, but for the runtime it's an ordinary synchronous function call.
To solve this problem you have to create and return a Promise
manually in getAllData()
and call the resolve()
callback after all requests have been completed:
async function getAllData(dealerId, id) {
return new Promise<any>((resolve, reject) => {
const options = {
'method': 'GET',
'url': _url '/' dealerId,
};
request.get(options, async function (error, response) {
if (error) {
reject(error);
return;
}
let partnerToken = response.body.slice(17,-2);
await getCarData(partnerToken,id);
await getCarImages(partnerToken, id);
_partnerToken = partnerToken;
resolve(returnValue); // <--- your return value
});
});
}
await getAllData(1, 2)