1
votes

I have a array of values I want to loop over. Each of these values will be used to make an http request to a server. From the server I will recieve a response for each request. I want to store all these responses in a single array and then do work on the array once ALL requests have finished. Due to the async nature of my code I am not sure how to make the application wait until all the requests have finished. What is happening is I am making the requests, but the work I want to do with the array is already starting before ALL the requests have finished due to the async nature. How can I make this code "synchronous" in the sence it waits until all requests have finished before starting to do the work with the listOfResponses array

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
list.forEach(function(word) {

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
  });
});


/* ******************************* 
HERE I WANT TO DO STUFF WITH listOfResponses ONCE ALL THE REQUESTS FINISH
********************************** */
3

3 Answers

6
votes

Just map it to an array of promises:

  const promises = list.map(word => new Promise(resolve => {
   var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
   request(url, {
     json: true
   }, (err, res) => {
     if (err) {
       return reject(err);
     }   
     resolve(res.body);
   });
 }));

Then you can get all the results using Promise.all :

 Promise.all(promises).then(results => {
  //...
 });
3
votes

Simply check the responses each time a request ends:

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
list.forEach(function(word) {

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
    check();
  });
});

// CHECK THE LIST
function check() {
  if (listOfResponses.length == list.length) {
    console.log("YAY! Here you have your responses", listOfResponses);
  }
}
1
votes

This is an asynchronous scenario, a way to accomplish that is calling recursively a function that will loop over your list of words. The recursion works according to each response from your server.

Another approach is using Promise.

Look this code snippet (Recursion approach):

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
var loop = function(array, index, cb) {  
  if (index === array.length)
      cb();
      return;

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + array[i];
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
    loop(array, i++, cb);
  });
};

loop(list, 0, function() {
      /* ******************************* 
         HERE I WANT TO DO STUFF WITH listOfResponses ONCE ALL THE REQUESTS FINISH
       ********************************** */
});       

As you can see, the loop starts with a call to loop function with index = 0 and every response will call the loop function with an incremented index.

The recursion ends when index == list.length and the callback is executed to keep the flow of your logic.