从Node.JS中的两个网站请求RSS提要

Mak*_*iev 4 javascript rss request node.js

我有一个Node.JS服务器,它从两个Web服务器请求数据:bbc.co.uksky.com.然后解析RSS提要,并且用户看到两个列表:来自BBC和来自天空.

这是代码.

var feed = require('feed-read');
var http = require('http');
var async = require('async');
var request = require('request');

var LIMIT = 10;
var UNABLE_TO_CONNECT = "Unable to connect.";
var BBC_URL = 'http://feeds.bbci.co.uk/news/rss.xml';
var SKY_URL = 'http://news.sky.com/feeds/rss/home.xml';

var server = http.createServer(onRequest);
server.listen(9000);

function onRequest(req, res) {
    res.writeHead(200, {
        'Content-Type' : 'text/html; charset=utf-8'
    });

    async.parallel([ function(callback) {
        feed(BBC_URL, onRssFetched);
        // TODO: where to call callback()?
    }, function(callback) {
        feed(SKY_URL, onRssFetched);
        // TODO: where to call callback()?
    } ], function done(err, results) {
        console.log("Done");
        if (err) {
            throw err;
        }
    });
}

function onRssFetched(err, articles) {
    console.log("RSS fetched");
    var html = [];
    if (err) {
        html.push("<p>", UNABLE_TO_CONNECT = "</p>");
    } else {
        html.push("<ol>");
        var i = 0;
        articles.forEach(function(entry) {
            if (i == LIMIT) {
                return;
            }
            html.push("<li><a href='" + entry.link + "'>" + entry.title
                    + "</a></li>");
            i++;
        });
    }
    console.log(html.join(""));
}
Run Code Online (Sandbox Code Playgroud)

现在我不知道如何将结果添加到网页.如果我callback()在调用feed方法后立即调用,callback()将在不等待feed完成其工作的情况下执行.另一方面,我不能传递callbackfeed.也许这种方法是错误的,我还需要一些其他模块来进行RSS解析.

nel*_*nic 13

@Maksim我知道您的原始问题包括异步模块,但提出了另一种选择:

为什么不将 每篇文章流式传输 到客户端,而不是在发送响应之前等待所有 RSS源返回...?

通过使用async.parallel,您告诉节点:

" 等到我们从响应 所有 这些新闻服务
,只有
那么 (物品组合成)一个 单一 的客户端的响应."

当您等待所有响应(来自RSS新闻服务)时,这会占用每个连接客户端的内存...... 浪费.

所以我写了我的答案而不诉诸异步.
并且,不是等待多年(当异步将所有提要合并为一个)时,
客户端会在第一个 RSS提要返回后立即看到新闻!

var feed = require('feed-read'),  // require the feed-read module
    http = require("http"),
    urls = [
        "http://feeds.bbci.co.uk/news/rss.xml",
        "http://news.sky.com/feeds/rss/home.xml",
        "http://www.techmeme.com/feed.xml"
    ]; // Example RSS Feeds

http.createServer(function (req, res) { 
    // send basic http headers to client
    res.writeHead(200, {
        "Content-Type": "text/html",
        "Transfer-Encoding": "chunked"
    });

    // setup simple html page:
    res.write("<html>\n<head>\n<title>RSS Feeds</title>\n</head>\n<body>");

    // loop through our list of RSS feed urls
    for (var j = 0; j < urls.length; j++) {

        // fetch rss feed for the url:
        feed(urls[j], function(err, articles) {

            // loop through the list of articles returned
            for (var i = 0; i < articles.length; i++) {

                // stream article title (and what ever else you want) to client
                res.write("<h3>"+articles[i].title +"</h3>"); 

                // check we have reached the end of our list of articles & urls
                if( i === articles.length-1 && j === urls.length-1) {
                    res.end("</body>\n</html>"); // end http response
                } // else still have rss urls to check
            } //  end inner for loop
        }); // end call to feed (feed-read) method
    } // end urls for loop
}).listen(9000);
Run Code Online (Sandbox Code Playgroud)

主要优势:

  • 连接到您的应用的人会看到新闻/结果更快(几乎立即!)
  • 应用程序使用多少 内存更少
  • 添加新RSS新闻源时,您无需编辑/更新任何代码!

有关此解决方案的更多详细信息/说明,
请参阅:https://github.com/nelsonic/node-parse-rss