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
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
- Those three requests should occur in order. You only call one when the previous one has a response and the callback fires. – Quentin Commented May 7, 2016 at 7:01
- See duplicate question: stackoverflow./questions/6048504/… – Miguel Boland Commented May 7, 2016 at 7:02
- Yeah this looks correct to me as well. See my answer on using Promises though. – user1893702 Commented May 7, 2016 at 7:08
-
You can't make them synchronous, but you can make them look synchronous (syntactically) . Take a look at
co
library andPromise
(part of ES6 standard ) – Yerken Commented May 7, 2016 at 7:15
2 Answers
Reset to default 5You 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.
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 pletes. Otherwise the setInterval
will cause the first request re-issued before the third request has an opportunity to plete. Which is likely the issue.