我正在创建一个简单的RSS Feed聚合器。为此,我使用了一个名为“盲解析器”的模块。该模块解析rss / xml字符串并返回一个对象。
我的目标是从多个rss feed获取这些对象并渲染它们。所以我最初这样做了:
var obj1 = {},obj2 = {}, obj3 = {};
app.get('/',function(req,res){
parser.parseURL('https://www.toptal.com/blog.rss', function (err, parsed1) {
obj1 = parsed1;
});
parser.parseURL('https://www.toptal.com/designers/blog.rss', function (err, parsed2) {
obj2 = parsed2;
});
parser.parseURL('http://jsfeeds.com/feed', function (err, parsed3) {
obj3 = parsed3;
});
parser.parseURL('http://www.mironov.com/feed/', function (err, parsed4) {
obj4 = parsed4;
});
res.render('index', {'toptal': obj1 , 'toptaldesign' : obj2 , 'jsf': obj3 , 'product': obj4 });
});
然而它并没有像obj1一样工作,obj2,obj3和obj4结果是未定义的。 我对此并不了解。我尝试在app.get和outside之外声明变量,两者都没有效果。
所以我这样做了,
app.get('/',function(req,res){
parser.parseURL('https://www.toptal.com/blog.rss', function (err, parsed1) {
parser.parseURL('https://www.toptal.com/designers/blog.rss', function (err, parsed2) {
parser.parseURL('http://jsfeeds.com/feed', function (err, parsed3) {
parser.parseURL('http://www.mironov.com/feed/', function (err, parsed4) {
res.render('index', {'toptal': parsed1 , 'toptaldesign' : parsed2 , 'rs': parsed3 , 'product': parsed4 });
});
});
});
});
});
并且它有效!然而,这种方法的主要缺点是,每次我嵌套另一个rss-link时,花费的时间增加2倍。
已经加载具有三层嵌套的页面所需的时间约为20秒。
有人可以帮助我并为此提供解决方案,我也是节点的新手,所以请详细说明。
感谢。
答案 0 :(得分:0)
我假设parse.parseURL
函数实际上是获取指定的URL并解析其内容。您的四个parseURL
请求中的每一个都是异步的,这意味着每个函数都是同步调用的,但是一旦获取了URL,它们的每个回调都会在稍后的某个时间执行。同时您的res.render
调用也已经在前面的parseURL
调用之后但在调用每个回调之前立即同步运行,所以在 obj1 等之前已经设置了。
当您在每个回调中嵌套调用时,如第二个示例中所示,那么您将确保在继续之前获取每个URL结果,但是当您按顺序提取每个URL时(例如,您不会获取第二个URL,直到第一个已经返回)然后执行时间会变慢。
您可以通过并行获取所有四个URL来加快速度(假设您的请求是同时处理的)。为此,如果您首先使用async之类的库,或者将代码转换为使用promises,则会更简单。如果您使用async,那么您的代码可以更改为并行获取URL,如下所示:
async.parallel([
( cb ) => {
parser.parseURL('https://www.toptal.com/blog.rss', cb );
},
( cb ) => {
parser.parseURL('https://www.toptal.com/designers/blog.rss', cb );
},
( cb ) => {
parser.parseURL('http://jsfeeds.com/feed', cb );
},
( cb ) => {
parser.parseURL('http://www.mironov.com/feed/', cb );
}
],
( err, results ) => {
// Called once all requests have completed.
res.render('index', {'toptal': results[0] , 'toptaldesign' : results[1] , 'jsf': results[2] , 'product': results[3] });
});