1

I'm trying to execute 3 'http requests'. The problem is, because of the nature of asynchronous mode, it doesn't execute in order. All requests are to internal apis. Here's the sample code :-

setInterval(function () {
  // First request
  request({}, function (error, response, body) {
   // Second request
   request({}, function (error, response, body) {
    // Third request
    request({}, function (error, response, body) {
    })
   })
  })
},1000);

What i'm trying to achieve is get data based on one condition (First request), update data (Second request) and send sms and emails (Third request). Because of the asynchronous nature, code is getting repeated many times. I'm using setInterval so the code will always run every second

Sandesh PS
  • 33
  • 2
  • 6
  • Those three requests **should** occur in order. You only call one when the previous one has a response and the callback fires. – Quentin May 07 '16 at 07:01
  • See duplicate question: http://stackoverflow.com/questions/6048504/synchronous-request-in-nodejs – Miguel Boland May 07 '16 at 07:02
  • Yeah this looks correct to me as well. See my answer on using Promises though. –  May 07 '16 at 07:08
  • You can't make them synchronous, but you can make them look synchronous (syntactically) . Take a look at `co` library and `Promise` (part of ES6 standard ) – Yerken May 07 '16 at 07:15

2 Answers2

5

You can easily sequence requests using Promises

// Load Dependencies: 
var Promise = require('promise');
var request = require('request');

// Begin Execution:
main();

function main() {
  getData()                //Executes 1st
   .then(updateData)       //Whatever is 'fulfilled' in the previous method, gets passed to this function updateData
   .then(sendNotification) //Whatever is fulfilled in the previoud method, gets passed to this function sendNotification.
   .catch(function(err) {
     console.log('If reject is called, this will catch it - ' +err);
   });
}

// Request #1:
function getData() {
  return new Promise(function(fulfill, reject) {
    request({}, function(err, res, body) {
      if (err) {
        reject('Error making request - ' +err);
      } else if (res.statusCode !== 200) {
        reject('Invalid API response - ' +body);
      } else {
        fulfill(body);
      }
    });
  });
}

// Request #2:
function updateData(data) {
  return new Promise(function(fulfill, reject) {
    request({}, function(err, res, body) {
      if (err) {
        reject('Error making request - ' +err);
      } else if (res.statusCode !== 200) {
        reject('Invalid API response - ' +body);
      } else {
        fulfill(body);
      }
    });
  });
}


// Request #3
function sendNotification(phoneNumber, email) {
  return new Promise(function(fulfill, reject) {
    request({}, function(err, res, body) {
      if (err) {
        reject('Error making request - ' +err);
      } else if (res.statusCode !== 200) {
        reject('Invalid API response - ' +body);
      } else {
        fulfill(body);
      }
    });
  });
}

So basically just wrap your async functions with return new Promise, to return the ready data via fulfill or reject. In function main(), you can see how the sequence for this order has been easily defined.

  • That won't solve the problem if the problem is a `setInterval` that causes the first request to occur repeatedly before the third has completed. – Dan D. May 07 '16 at 07:27
  • But why is `setInterval` being used in the first place? Only because of a lack of a proper understanding is why I thought. –  May 07 '16 at 07:37
  • @love I would like to run the entire process every one second – Sandesh PS May 07 '16 at 07:49
  • @sandeshps Can you just wrap `main()` in setInterval then? Or do you only want it to repeat once the previous three have finished? –  May 10 '16 at 05:10
1

Answer to title: You can't make them synchronous. But you can sequence them.

You likely should replace the setInterval with a setTimeout and then issue another setTimeout after the third request completes. Otherwise the setInterval will cause the first request re-issued before the third request has an opportunity to complete. Which is likely the issue.

Dan D.
  • 73,243
  • 15
  • 104
  • 123