保存异步功能的结果供以后使用

时间:2013-12-25 20:48:05

标签: node.js asynchronous

我最近开始学习node.js,这是我对异步函数的第一个方法,但我无法绕过它。我很难解释我的意思,所以我举一个例子。

在下面的代码中,我使用异步库来遍历一组twitter用户名并获取他们最新的推文(使用twitter库,twit变量)。所有的推文都作为一个数组收集在结果变量中,我可以在最后一个回调函数中使用它。相似性是我写的一个函数,它只返回一个数字。

async.map(screenNames,function(name,callback){
    twit.get('/statuses/user_timeline.json', {screen_name: name, count : 1}, function(data) {
        callback(null,data[0]['text']);

    });
},function(err,results){
console.log(similarity(results));
});

现在说我想使用setInterval每隔X秒重复一次这个操作,每次检查用户是否发布了一些新内容(即如果我们刚刚发布的推文与我们以前的推文不同),如果有的话,存储他们的新推文等。
如何存储他们的推文以将它们与每次迭代的结果进行比较?

我尝试了以下操作但没有成功。

setInterval(function(){
    async.map(screenNames,function(name,callback){
        twit.get('/statuses/user_timeline.json', {screen_name: name, count : 1}, function(data) {
            callback(null,data[0]['text']);
        });
    },function(err,results){
    console.log(similarity(results));
    });
    console.log(results+'outside async');
},2000,[screenNames,similarity]);

导致“console.log(结果+'异步外');结果未定义”

然后我试了

setInterval(function(){
    async.map(screenNames,function(name,callback){
        twit.get('/statuses/user_timeline.json', {screen_name: name, count : 1}, function(data) {
            callback(null,data[0]['text']);
        });
    },function(err,results){
    console.log(similarity(results));
    });
    //console.log(results);
},2000,[screenNames,similarity]);

导致一次正确的迭代然后“回调(null,data [0] ['text']); 无法读取未定义的属性“文本”“(我很确定这并不完全相关)

最后

setInterval(function(){
    async.map(screenNames,function(name,callback){
        twit.get('/statuses/user_timeline.json', {screen_name: name, count : 1}, function(data) {
            callback(null,data[0]['text']);
        });
    },function(err,results){
    console.log(results);
    });
    console.log(results+'outside async');
},2000,[screenNames]);

再次导致“console.log(结果+'异步外部');结果未定义”

有人能指出我犯错误的地方吗?也许是我接近这个方式的缺陷? 非常感谢您阅读我的问题。


编辑:似乎我的相似性函数以某种方式打破了应用程序。这是一个非常大的功能,所以我会发布截断版本。

function similarity(phrases){
    if(phrases.length ==2){
    //Lots of stuff
    //concerning the phrases happen here
    // and a variable called similarity is produced which
    //contains a number
        return similarity;
    }else{
        throw "Can only find similarity between 2 phrases"; 
    }   
}

1 个答案:

答案 0 :(得分:1)

您的第一个和第三个方法很糟糕,因为结果只是在async.map的回调中定义,所以它没有在setInterval中定义。我不知道你的第二个问题是什么,但无论如何,我会这样做:

var screenNames = [initial data];
var lastTweets = null;
setInterval(function(){
    async.map(screenNames,function(name,callback){
        twit.get('/statuses/user_timeline.json', {screen_name: name, count : 1}, function(data) {
            callback(null,data[0]['text']);
        });
    },function(err,results){
      if ( lastTweets == null )
        lastTweets = results
      else
      for (var i = 0; i < results.length; i++){
        if (lastTweets[i] != results[i] ) {
          // do something
          lastTweets[i] = results[i];
        }
      }
    });
},2000);

请注意,如果screenNames数组发生了变化,那么这将是一个问题,所以我会把它放到一个对象中,如下所示:

var screenNames = [{name:'name', lastTweet:''},...];
setInterval(function(){
    async.map(screenNames,function(name,callback){
        twit.get('/statuses/user_timeline.json', {screen_name: name.name, count : 1}, function(data) {
            callback(null,data[0]['text']);
        });
    },function(err,results){
      for (var i = 0; i < results.length; i++){
        if (screenNames[i].lastTweet != results[i] ) {
          // do something
          screenNames[i].lastTweet = results[i];
        }
      }
    });
},2000);