Home > Back-end >  Response is send immediately and does not wait for await
Response is send immediately and does not wait for await

Time:07-19

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)
  • Related