2

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 Answers 3

7

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 => {
  //...
 });
Sign up to request clarification or add additional context in comments.

Comments

4

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

2 Comments

I will use promises I think, but I like this solution as well!
@user2924127 Yep, promises is way more clean.
2

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.

2 Comments

One should note that this executes one request after another, which might be slower.
@JonasW. you're right, however, depends on how the OP wants to process the data, either the whole set in parallel or one by one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.