2017-06-12 103 views
0

我有一个节点项目实现快速处理传入的GET/POST请求,我创建了处理不同类型的请求的路由。我作为/api/twitter/search的路线基本上调用使用的承诺来获取Twitter的饲料,并使用response.writeNode Express JS - 处理同时POST请求到服务器

现在这里的情况是响应发送数据的功能,当我提出两个具有相同输入的同时请求同一路线数据,然后不知何故这两个请求的运行代码重合,给出不一致的响应。我希望单独处理到服务器的任意数量的请求,即使对请求的操作具有一定数量的异步调用/许诺。

任何人都可以请帮助我在这里。我完全新的js开发,所以任何帮助将不胜感激

以下是代码:

,我已经创建的路线去如下:

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

以下是该代码fetchTweets功能:

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(); 
     }); 
    } 
}; 
+0

我想你解释错了,“我用相同的输入数据向同一路线发出两个同时请求,然后不知何故两个请求的结果一致”你甚至表示什么意思?在相同的get和input数据上给出相同的结果来定义一致性,你想说什么? –

+0

对不起,我还不够清楚。事情是我用url输入postman:localhost:8080/api/twitter/fetch用一些输入数据。此路由链接到使用输入数据使用res.write返回某些输出的方法。 当我同时打两次相同的URL时,通过打开两个邮递员选项卡,服务器不会将其作为两个不同的请求处理,而是在第二个实例中使用第一个请求主体的请求主体,反之亦然 –

+2

听起来你没有正确地声明变量,所以他们被“提升”为全局变量。当然,我们只能猜测,因为你没有发布任何代码。 – robertklep

回答

2

意外行为处理的并发请求,特别是当一个请求似乎“影响”另一请求时,几乎总是由未声明的变量导致(正确使用var,letconst)。

这可能会导致这些变量变成全局变量,这意味着它们在所有请求之间共享,这可能会导致各种问题。

如果可能,将linter支持添加到您的编辑器可能有助于捕捉这些情况。对于Vim,一个常用的插件是syntastic,它可以使用eslint来对JS代码进行语法检查。几乎所有常见编辑器都有等效的插件。

+0

我仍然面临这个问题。谢天谢地,我现在可以访问代码了,我将编辑这个问题,并立即发布答案。我很确定声明可能是问题,但不知道如何在给定的代码中处理它。请帮忙! –

+0

错误地声明或未声明的变量:'returnObject','created_at','max_id','return_arr'和'tweetArr'。 – robertklep

+0

您可以请尝试在您的最后运行代码。即使通过'var'在本地定义它们,我也无法找到解决方案。请注意,如果您设置了从路由代码 –