2013-12-10 16 views
6

Sto cercando di avvolgere la mia mente su Node.js e alcune operazioni asincrone. Nel codice seguente, recupero alcuni feed RSS e memorizzo gli articoli trovati se non li ho memorizzati prima. Il codice funziona e memorizza nuovi articoli. Tuttavia, non sono sicuro di come modificare questo in modo da sapere quando tutti gli articoli sono stati analizzati. Ad esempio, il callback su ogni async.eachLimit viene chiamato ogni volta che viene raggiunto il limite (dopo 10 articoli o 5 feed). Quindi, come faccio a sapere quando hanno finito?node.js callback async.each, come faccio a sapere quando è finito?

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

Uhm, la richiamata viene chiamato dopo tutte le operazioni asincrone in l'iterazione ha completato, Siete alla ricerca di qualcosa di diverso? – adeneo

risposta

5

Per prima cosa, si invitano preventivamente le proprie richiamate troppo presto.

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

    callback(); 
} 

Non si dovrebbe essere chiamando callback prima il gioco è fatto. Altrimenti verrà chiamato il metodo "finito", ma il codice asincrono sarà ancora in esecuzione.

Così, invece di fare:

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

Basta fare

.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! Eccoci. Ho spostato il callback in 'eachLimit' relativo agli articoli. Risolto tutto Grazie! – tubaguy50035

+2

Si tratta semplicemente di mantenere le cose semplici, in futuro lavorare con una funzione con più nomi (rispetto a quelle anonime) e sarà più facile per te vedere dove porta il flusso asincrono. – bevacqua

+0

Inoltre, dare ai callback nomi più appropriati è davvero utile, mi piace usare 'next' e' done' per differenziarli, per esempio. – bevacqua

Problemi correlati