Reputation: 655
I have a node project implementing express to handle incoming GET/POST requests, I have created routes to handle different kinds of requests. I have a route as /api/twitter/search
which basically calls a function that uses promises to fetch twitter feeds and sends the data in response using response.write
Now the situation here is, when I make two simultaneous requests to the same route with the same input data, then somehow the running code of both the requests coincide giving inconsistent response. I want any number of requests to the server to be handled separately, even if the action to the request has a number of async calls/promises in place.
Can anyone please help me here. I am totally new to js development, so any help will be appreciated
Following is the code:
The route that I have created goes as follows:
app.post('/api/twitter/fetch',function(req,res){
var hashTag = req.body.hashtag;
var userVals = {
userEmail: req.body.uemail,
tokenVal: req.body.utoken
}
tokenController.validateToken(userVals,function(error,data){
returnObject = {status:true, data:'', error:''};
if(error!=''){
returnObject.status = false;
returnObject.data = data;
returnObject.error = error;
res.send(returnObject);
}else{
var twitterController = require('../controllers/testTwitterController');
twitterController.fetchTweets(res,hashTag);
}
});
});
Following is the code for the fetchTweets function:
var Twitter = require('twitter');
var params = require('../config/params.js');
var moment = require('moment');
//var promise = require('promise');
var globalHashTag = ''; var tweetArr = []; var responseHandle = [];
client = new Twitter({
consumer_key: params.consumer_key,
consumer_secret: params.consumer_secret,
access_token_key: params.access_token_key,
access_token_secret: params.access_token_secret
});
function fetchTweetsAsync(hashTag,max_id){
var days = 7; //Days you want to subtract from today
var tillDate = (new Date()).toISOString().split('T')[0];
var sinceDate = (new Date((new Date).getTime() - ((days) * 24 * 60 * 60 * 1000))).toISOString().split('T')[0];
var param = {q:'#'+hashTag+' since:'+sinceDate+' until:'+tillDate,include_entities:true,result_type:'recent',count:100};
if(max_id !== '' || typeof max_id != undefined)
param.max_id = max_id;
return new Promise(function(resolve,reject){
// do a thing, possibly async, then..
client.get('search/tweets',param,function(error,tweets,response){
if(error){
console.log(error);
process.exit(1);
}
if(tweets.statuses.length){//If we get tweets, send them via promise
//console.log("\n\n\n\n--------------------------------------------------------- Tweets fetched for #"+hashTag+ "-------------------------------------------------------------\n\n\n");
resolve(tweets.statuses,hashTag);
}
});
});
};
function getMaxHistory(tweets,hash){
//console.log("\n\n~~~~~~~~~~~~~~~~Total: "+ tweets.length + " results found!~~~~~~~~~~~~~~~~\n\n");
tweets.map((tweet)=>{
process.stdout.write('.');
created_at = moment(tweet.created_at).format("YYYY-MM-DD");
tweetArr.push(created_at);
});
max_id = tweets[tweets.length - 1].id - 1;
if(tweets.length == 100){
process.stdout.write('*');
return fetchTweetsAsync(hash,max_id).then(getMaxHistory);
}
else{
var total = tweetArr.length;
var finalArr = [];
finalArr = getDateWiseCount(tweetArr);
tweetArr = [];
console.log("Count array generated!");
console.log("Total: "+total);
finalArr = JSON.stringify({status:true,total:total,counts:finalArr});
return finalArr;
// console.log(finalArr);
//responseHandle.send([{status:true,total:total,counts:finalArr}]);
}
}
function getDateWiseCount(tweetArr){
tweetArr = tweetArr.sort(); //We have a sorted array, need to get the counts now
var current = null;
var count = 0; returnarr = [];
for(var i = 0; i < tweetArr.length; i++)
{
if(tweetArr[i] != current)
{
if(count > 0)
{
var date = new Date(current).toISOString();
var val = count;
returnarr.push({date:date,value:val});
//console.log(returnarr);
//console.log(current + " " + count + "<br/>");
}
current = tweetArr[i];
count = 1;
}
else
{
count++;
}
}
if(count > 0){
var date = new Date(current).toISOString();
var val = count;
returnarr.push({date:date,value:val});
}
return returnarr;
}
module.exports = {
fetchTweets: function(res,hashTag){
responseHandle = res;
fetchTweetsAsync(hashTag).then(getMaxHistory).then(function(finalArr){
res.write(finalArr);
res.end();
});
}
};
Upvotes: 4
Views: 1678
Reputation: 203241
Unexpected behaviour when handling concurrent requests, especially where one request seems to "influence" another request, are almost always caused by variables not being declared (using var
, let
or const
) properly.
This may cause these variables to become globals, meaning that they get shared among all requests, which can lead to all kinds of issues.
If possible, adding linter support to your editor may help catch these situations. For Vim, a commonly used plugin is syntastic
, which can use eslint
to syntax-check JS code. There are equivalent plugins for almost all common editors.
Upvotes: 4