2016-07-08 2 views
0

Я работаю над проектом, где мне нужно сделать несколько запросов к стороннему API, а затем отправить массив данных, полученных на клиент. Очевидно, что запросы к стороннему API являются асинхронными, и если я поместил res.json сразу после цикла запроса, данные будут пустыми. Нужно ли обертывать запрос в обещание? Вот мой код:Как отправить ответ после нескольких запросов к стороннему API Node.js

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); 
     }); 
     } 
    } 
    }); 
}; 
+2

Вы хотите использовать promisified версию 'request', а затем использовать' Promise.all() ', чтобы знать, когда все ваши запросы сделано. Этот вопрос, вероятно, был задан много раз, поэтому, возможно, есть много других ответов, которые описывают это. – jfriend00

+1

Вот общая структура для использования обещаний знать, когда выполняются несколько асинхронных операций: http://stackoverflow.com/questions/32799672/node-js-how-to-set-a-variable-outside-the-current-scope/32799727 # 32799727 – jfriend00

+0

Благодарим вас за советы. @ jfriend00 – Atache

ответ

0

В соответствии с @ jfriend00-х внушения я посмотрел на:

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

И использовали один из многих вариантов, представленных здесь. Мое решение находится в сообщении выше. Будет закладка этой должности для дальнейшего использования.

я заменил весь код в другое, если оператор с:

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

Правильный способ использования переполнения стека заключается в том, чтобы вставить ваш фактический закодированный ответ в свой ответ и удалить его из вашего вопроса. В отличие от некоторых других сайтов, вопросы должны быть только вопросами, и ответы здесь должны быть только ответами. Поэтому, пожалуйста, выньте свое решение из своего вопроса и поместите его в свой ответ здесь. Затем вы можете «принять» свой собственный ответ на вопрос (как только пройдет определенное количество времени), чтобы сообщить сообществу, что на ваш вопрос был дан ответ. Вы могли бы также поддержать связанный ответ, который показал вам путь. – jfriend00

Смежные вопросы