2013-12-10 69 views
6

我想绕过Node.js和一些异步操作。在下面的代码中,我获取一些RSS提要并存储发现的文章,如果我以前没有存储它们的话。该代码工作并存储新文章。不过,我不知道如何改变这一点,以便我知道所有文章何时完成解析。例如,每次调用每个async.eachLimit时都会调用回调(10条或5条提交后)。那么我怎么知道他们什么时候完成了?node.js async.each回调,我怎么知道它什么时候完成?

var FeedParser = require('feedparser'); 
var request = require('request'); 
var mysql = require('mysql'); 
var async = require('async'); 

var connection = mysql.createConnection({ 
     host : 'localhost', 
     user : 'someuser', 
     password : 'somepass', 
     database : 'somedb' 
}); 

connection.connect(); 

connection.query('SELECT * FROM rssfeed', function(err, rows, fields) { 
     if(err == null){ 
       async.eachLimit(rows, 5, parseFeed, function(err) { 
         if(! err) { 
           //horray 
         } else { 
           console.log(err); 
         } 
       }); 
     } 
}); 

function parseFeed(feed, callback) { 
     var articles = []; 
     request(feed.link) 
     .pipe(new FeedParser()) 
     .on('error', function(error) { 
       callback(error); 
     }) 
     .on('meta', function(meta) { 
     }) 
     .on('readable', function() { 
       var stream = this, item; 
       item = stream.read(); 
       if(item != null) { 
         item.rssfeed_id = feed.id; 
         articles.push(item); 
       } 
     }) 
     .on('finish', function() { 
       async.eachLimit(articles, 10, parseArticle, function(err) { 
         if(! err) { 
           console.log('article each callback'); 
         } else { 
           callback(error); 
         } 
       }); 
     }); 
     callback(); 
} 
function parseArticle(item, callback) { 
     if(item.hasOwnProperty('rssfeed_id') && item.hasOwnProperty('guid') && item.hasOwnProperty('link') && item.hasOwnProperty('title')){ 
       connection.query('SELECT * FROM rssarticle WHERE rssfeed_id = ? AND guid = ?', [item.rssfeed_id, item.guid], function(err, rows, fields) { 
         if(rows.length == 0){ 
           connection.query('INSERT INTO rssarticle SET ?', { 
             rssfeed_id: item.rssfeed_id, 
             link: item.link, 
             title: item.title, 
             description: item.description, 
             publish_date: item.pubDate, 
             guid: item.guid 
           }, function(err, result){ 
             if(err != null){ 
               console.log(err); 
             } 
           }); 
         } 
       }); 
     } 
     callback(); 
} 
+0

嗯,在迭代的所有异步操作完成后调用回调,你在找什么东西? – adeneo

回答

5

其中之一,你抢先调用你的回调方式太早。

function parseFeed(feed, callback) { 
    request 
    .streamStuff() 
    .streamStuff() 
    .streamStuff(); 

    callback(); 
} 

在完成之前,您不应该拨打callback。否则,你的“完成”方法将被调用,但你的异步代码实际上仍然在运行。

所以不是这样做的:

.on('finish', function() { 
    async.eachLimit(articles, 10, parseArticle, function(err) { 
     if(! err) { 
      console.log('article each callback'); 
     } else { 
      callback(error); 
     } 
    }); 
}); 
callback(); 

只是做

.on('finish', function() { 
    async.eachLimit(articles, 10, parseArticle, function(err) { 
     if(! err) { 
      // assuming this is a stub and really ends up doing `callback();` 
      console.log('article each callback'); 
     } else { 
      callback(error); 
     } 
    }); 
}); 
+0

AHA!我们走了。我将回调移到了与articles相关的'eachLimit'中。修复了一切。谢谢! – tubaguy50035

+2

所有这些都是为了让事情变得简单,在将来使用更多命名函数(而不是匿名函数)时,您会更容易看到异步流程的位置。 – bevacqua

+0

此外,给回调更合适的名称是非常有用的,例如,我喜欢使用'next'和'done'来区分它们。 – bevacqua

相关问题