What happens when you want to make a bunch of asynchronous http requests and you need them to be executed one after the other? That is, you don't want the next call to start until the first one finishes. Lets imagine a scenario where you want the results of each request to be collected into an array in order. To solve this problem you need to invoke the requests synchronously. Lets look at an example using Node's http module.

If you want to make 20 different get requests to 20 different urls, the first thing you can do is keep all the urls in an array as strings. We'll also set up an empty array to collect our results.

var URLs =  ['www.api.com/doc1','www.api.com/doc2','www.api.com/doc3'...etc];

var results = [];

Then you can write a recursive function that pops urls off of the storage array, makes get requests on them, and then repeats until the array is empty. At the very end, when there are no more calls to make, you return the collected results.

function synchAPICalls (urls) {
  var url = urls.pop();
  http.get(url,function(res){
      var chunks = '';
    res.on('data',function(d){
      chunk += d;
    });
    res.on('end',function(){
      results.push(chunks);
      if(urls.length){
        synchAPICalls(URLs);
      } else {
        return results;
      }
    })
  })
}
synchAPICalls(URLs)

We can think of other use cases for synchronous API calls as well. Lets say you need to wait 5 seconds between each API call. In that case, you can insert a setTimeout into your recursive function like so:

function synchAPICalls (urls) {
  var url = urls.pop();
  setTimeout(function(){
    http.get(url,function(res){
      var chunks = '';
    res.on('data',function(d){
      chunk += d;
    });
    res.on('end',function(){
      //do stuffed with chunked result
      if(urls.length){
        synchAPICalls(URLs);
      } else {
        console.log('all done!');
      }
    })
  })
  },5000); 
}
synchAPICalls(URLs)

I use this trick pretty frequently, it's a very simple way to synchronize many asynchronous processes.

comments powered by Disqus