如何在向第三方API Node.js发出多个请求后发送响应

时间:2022-05-01 22:58:59

I am working on a project where I need to make multiple requests to a third party API and then send back an array of the data recieved to the client. Obviously the requests to the to the third party API are async, and if I put the res.json immediately after the request loop, the data will be empty. Do I need to wrap the request in a promise? Here is my code:

我正在开发一个项目,我需要向第三方API发出多个请求,然后将收到的数据数据发送回客户端。显然,对第三方API的请求是异步的,如果我在请求循环之后立即放入res.json,则数据将为空。我是否需要将请求包含在承诺中?这是我的代码:

const historicalForecast = (req, res, next) => {
  console.log(req.body);
  // GET COORDS FROM GOOGLE API BY LOCATION INPUT BY USER
  let googleUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${req.body.input}&key=${googleKey}`;
  request(googleUrl, function(error, response, body){
    if(error){
      console.log(error);
      next();
    }
    let data = JSON.parse(response.body);
    //IF MORE THAN ONE RESULT FROM GEOLOCATION QUERY
    //ADD DATES REQUESTED INTO RESPONSE AND
    //SEND LIST OF LOCATIONS BACK SO USER CAN CHOOSE
    if(data.results.length > 1){
      response.body.startDate = req.body.startDate;
      response.body.endDate = req.body.endDate;
      res.json(JSON.parse(response.body));

    //IF ONE RESULT, GET DATA IN BATCHES
    }else if(data.results.length === 1) {
      let coords = data.results[0].geometry.location;
      const OneDay = 86400;
      let timeFrame = Math.abs(req.body.startDate - req.body.endDate);
      let numberOfDays = timeFrame/OneDay;
      console.log(numberOfDays);
      let results = [];

      for(let i = 0; i < numberOfDays; i++){
        let currentDay = Number(req.body.startDate) + (i*OneDay);
        let urlWeather = `https://api.forecast.io/forecast/${weatherKey}/${coords.lat},${coords.lng},${currentDay}`;
        request(urlWeather, function(error, response, body){
          if(error){
            console.log(error);
            next();
          }
          results.push(JSON.parse(response.body));
          res.send(results);
        });
      }
    }
  });
};

1 个解决方案

#1


0  

As per @jfriend00's suggestion I looked at:

根据@jfriend00的建议,我看了一下:

Node.JS How to set a variable outside the current scope

Node.JS如何在当前范围之外设置变量

And used one of the many options provided there. My solution is in the post above. Will be bookmarking that post for future reference.

并使用了那里提供的众多选项之一。我的解决方案在上面的帖子中。将该帖子加入书签以供将来参考。

I replaced all the code in the else if statement with:

我用else if语句替换了所有代码:

  let coords = data.results[0].geometry.location;
  const OneDay = 86400;
  let timeFrame = Math.abs(req.body.startDate - req.body.endDate);
  let numberOfDays = timeFrame/OneDay;


  const makeMultipleQueries = (url) => {
    return new Promise(function(resolve, reject) {
      request(url, function(error, response, body){
        if(error){
          reject(error);
        }
        resolve(response.body);
      });
  });
};

let promises = [];
for (let i = 0; i < numberOfDays; i++) {
  let currentDay = Number(req.body.startDate) + (i*OneDay);
  let url = `https://api.forecast.io/forecast/${weatherKey}/${coords.lat},${coords.lng},${currentDay}`;
  promises.push(makeMultipleQueries(url));
}
Promise.all(promises).then(function(results) {
    res.json(results);
}, function(err) {
    next(err);
});

#1


0  

As per @jfriend00's suggestion I looked at:

根据@jfriend00的建议,我看了一下:

Node.JS How to set a variable outside the current scope

Node.JS如何在当前范围之外设置变量

And used one of the many options provided there. My solution is in the post above. Will be bookmarking that post for future reference.

并使用了那里提供的众多选项之一。我的解决方案在上面的帖子中。将该帖子加入书签以供将来参考。

I replaced all the code in the else if statement with:

我用else if语句替换了所有代码:

  let coords = data.results[0].geometry.location;
  const OneDay = 86400;
  let timeFrame = Math.abs(req.body.startDate - req.body.endDate);
  let numberOfDays = timeFrame/OneDay;


  const makeMultipleQueries = (url) => {
    return new Promise(function(resolve, reject) {
      request(url, function(error, response, body){
        if(error){
          reject(error);
        }
        resolve(response.body);
      });
  });
};

let promises = [];
for (let i = 0; i < numberOfDays; i++) {
  let currentDay = Number(req.body.startDate) + (i*OneDay);
  let url = `https://api.forecast.io/forecast/${weatherKey}/${coords.lat},${coords.lng},${currentDay}`;
  promises.push(makeMultipleQueries(url));
}
Promise.all(promises).then(function(results) {
    res.json(results);
}, function(err) {
    next(err);
});