javascript - node.js async.each callback, hvordan vet jeg når det er ferdig?
Jeg prøver å forstå Node.js og noen asynkrone operasjoner. I følgende kode henter jeg noen RSS-feeder og lagrer artiklene som blir funnet hvis jeg ikke har lagret dem før. Koden fungerer og lagrer nye artikler. Jeg er imidlertid ikke sikker på hvordan jeg skal endre dette slik at jeg vet når alle artiklene er ferdig analysert. For eksempel blir callbacken på hver async.eachLimit kalt hver gang grensen er nådd (etter 10 artikler eller 5 feeder). Så hvordan vet jeg når de er ferdige?
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();
}
Svar #1
For det første kaller du tilbakefunksjonene dine altfor tidlig på forhånd.
function parseFeed(feed, callback) {
request
.streamStuff()
.streamStuff()
.streamStuff();
callback();
}
Du bør ikke kalle callback før du er ferdig. Ellers vil metoden din "finished" bli kalt, men koden din som kjører asynkront vil faktisk fortsatt være i gang.
Så i stedet for å gjøre:
.on('finish', function() {
async.eachLimit(articles, 10, parseArticle, function(err) {
if(! err) {
console.log('article each callback');
} else {
callback(error);
}
});
});
callback();
Bare gjør
.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);
}
});
});
