جافاسكريبت - node.js async.each رد الاتصال، كيف أعرف متى ينتهي؟
أنا أحاول أن أفهم Node.js وبعض العمليات غير المتزامنة. في الكود التالي، أقوم بجلب بعض خلاصة RSS وأخزن المقالات التي تم العثور عليها إذا لم أقم بتخزينها من قبل. الكود يعمل ويخزن المقالات الجديدة. ومع ذلك، لست متأكدًا من كيفية تغييره بحيث أعرف متى يتم تحليل جميع المقالات. على سبيل المثال، يتم استدعاء الدالة callback على كل async.eachLimit في كل مرة يتم فيها استيفاء الحد (بعد 10 مقالات أو 5 خلاصة). فكيف أعرف متى تنتهي جميعها؟
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();
}
الإجابة رقم 1
أولاً، أنت تستدعي ردود الاتصال الخاصة بك بشكل مبكر جدًا مسبقًا.
function parseFeed(feed, callback) {
request
.streamStuff()
.streamStuff()
.streamStuff();
callback();
}
لا يجب عليك استدعاء callback قبل أن تنتهي. وإلا فإن طريقتك "finished" ستُستدعى ولكن كودك غير المتزامن سيظل يعمل بالفعل.
بدلاً من القيام بـ:
.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);
}
});
});
