我最近开始学习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";
}
}
答案 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);