Node Express JS - 处理对服务器的同时POST请求

时间:2017-06-12 11:20:50

标签: javascript node.js express npm

我有一个实现express的节点项目来处理传入的GET / POST请求,我创建了处理不同类型请求的路由。我的路由为/api/twitter/search,它基本上调用一个函数,该函数使用promises来获取twitter提要并使用response.write

发送数据作为响应

现在的情况是,当我使用相同的输入数据对同一路由发出两个同时请求时,两个请求的运行代码会以某种方式重合,从而产生不一致的响应。我希望单独处理对服务器的任意数量的请求,即使对请求的操作有多个异步调用/承诺。

任何人都可以在这里帮助我。我是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();
        });
    }
};

1 个答案:

答案 0 :(得分:2)

处理并发请求时出现意外行为,特别是在一个请求似乎影响&#34;另一个请求,几乎总是由未正确声明的变量(使用varletconst)引起的。

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

如果可能,向编辑器添加linter支持可能有助于捕获这些情况。对于Vim,常用的插件是syntastic,它可以使用eslint来检查JS代码。几乎所有常见编辑都有相同的插件。