Nodejs 比较基础的问题

Nodejs 比较基础的问题

var eventproxy = require(‘eventproxy’); var superagent = require(‘superagent’); var cheerio = require(‘cheerio’); var url = require(‘url’);

var cnodeUrl = ‘https://cnodejs.org/’;

superagent.get(cnodeUrl) .end(function (err, res) { if (err) { return console.error(err); } var topicUrls = []; var $ = cheerio.load(res.text); $(’#topic_list .topic_title’).each(function (idx, element) { var $element = $(element); var href = url.resolve(cnodeUrl, $element.attr(‘href’)); topicUrls.push(href); });

var ep = new eventproxy();

ep.after(‘topic_html’, topicUrls.length, function (topics) { topics = topics.map(function (topicPair) { var topicUrl = topicPair[0]; var topicHtml = topicPair[1]; var $ = cheerio.load(topicHtml); return ({ title: $(’.topic_full_title’).text().trim(), href: topicUrl, comment1: $(’.reply_content’).eq(0).text().trim(), }); });

console.log(‘final:’); console.log(topics); });

topicUrls.forEach(function (topicUrl) { superagent.get(topicUrl) .end(function (err, res) { console.log(‘fetch ’ + topicUrl + ’ successful’); ** ep.emit(‘topic_html’, [topicUrl, res.text]);** }); });

});

中的 [topicUrl, res.text] 是什么意思???


4 回复

在你提供的代码中,[topicUrl, res.text] 是一个数组,用于传递两个值:当前主题的 URL 和该主题页面的 HTML 内容。具体来说,[topicUrl, res.text] 这个数组被用来作为参数调用 ep.emit('topic_html', [topicUrl, res.text]) 方法。

解释

  • topicUrl 是当前主题页面的 URL。
  • res.text 是通过 superagent.get(topicUrl) 请求获取到的 HTML 页面内容。

这些信息被传递给 EventProxyemit 方法,用于处理异步请求的结果。

示例代码解析

var eventproxy = require('eventproxy');
var superagent = require('superagent');
var cheerio = require('cheerio');
var url = require('url');

var cnodeUrl = 'https://cnodejs.org/';

superagent.get(cnodeUrl)
.end(function (err, res) {
  if (err) {
    return console.error(err);
  }
  
  var topicUrls = [];
  var $ = cheerio.load(res.text);
  
  $('#topic_list .topic_title').each(function (idx, element) {
    var $element = $(element);
    var href = url.resolve(cnodeUrl, $element.attr('href'));
    topicUrls.push(href);
  });

  var ep = new eventproxy();

  ep.after('topic_html', topicUrls.length, function (topics) {
    topics = topics.map(function (topicPair) {
      var topicUrl = topicPair[0];
      var topicHtml = topicPair[1];
      var $ = cheerio.load(topicHtml);
      
      return ({
        title: $('.topic_full_title').text().trim(),
        href: topicUrl,
        comment1: $('.reply_content').eq(0).text().trim(),
      });
    });

    console.log('final:');
    console.log(topics);
  });

  topicUrls.forEach(function (topicUrl) {
    superagent.get(topicUrl)
      .end(function (err, res) {
        console.log('fetch ' + topicUrl + ' successful');
        
        // 发送事件并传递 topicUrl 和 res.text
        ep.emit('topic_html', [topicUrl, res.text]);
      });
  });
});

代码中的关键点

  1. 获取页面内容

    • superagent.get(cnodeUrl) 获取 CNode 首页的内容,并使用 Cheerio 解析 HTML 来提取每个话题的链接。
  2. 异步请求处理

    • ep.after('topic_html', topicUrls.length, ...) 等待所有话题页面请求完成。
    • ep.emit('topic_html', [topicUrl, res.text]) 在每个话题页面请求完成后触发事件,并传递 topicUrlres.text
  3. 数据处理

    • 最终将所有话题的信息收集起来并打印出来。

通过这种方式,可以有效地处理多个异步请求,并在所有请求完成后进行统一的数据处理。


就是普通变量的意思

就是就地创建了一个数组,里面有两个值分别是 topicUrl 和 res.text

[topicUrl, res.text] 是一个数组,其中包含两个元素:

  • topicUrl 是当前抓取的帖子的 URL。
  • res.text 是抓取到的 HTML 内容。

在代码中,[topicUrl, res.text] 被传递给 ep.emit('topic_html', [topicUrl, res.text]) 方法。这表示当一个帖子的 HTML 内容被成功抓取后,将该帖子的 URL 和 HTML 内容一起发送给事件代理 eventproxy,以便后续处理。

例如,当抓取到第一个帖子的 HTML 内容时,会触发一次 ep.emit,传递的参数为 [topicUrl1, res.text1];同理,当抓取到第二个帖子的 HTML 内容时,会触发另一次 ep.emit,传递的参数为 [topicUrl2, res.text2],依此类推。

最终,当所有帖子的 HTML 内容都抓取完毕后,事件代理 eventproxy 将收集到的所有 [topicUrl, res.text] 对通过回调函数进行处理,提取所需的信息(如标题、评论等)。

回到顶部