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] 是什么意思???
在你提供的代码中,[topicUrl, res.text]
是一个数组,用于传递两个值:当前主题的 URL 和该主题页面的 HTML 内容。具体来说,[topicUrl, res.text]
这个数组被用来作为参数调用 ep.emit('topic_html', [topicUrl, res.text])
方法。
解释
topicUrl
是当前主题页面的 URL。res.text
是通过superagent.get(topicUrl)
请求获取到的 HTML 页面内容。
这些信息被传递给 EventProxy
的 emit
方法,用于处理异步请求的结果。
示例代码解析
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]);
});
});
});
代码中的关键点
-
获取页面内容:
superagent.get(cnodeUrl)
获取 CNode 首页的内容,并使用 Cheerio 解析 HTML 来提取每个话题的链接。
-
异步请求处理:
ep.after('topic_html', topicUrls.length, ...)
等待所有话题页面请求完成。ep.emit('topic_html', [topicUrl, res.text])
在每个话题页面请求完成后触发事件,并传递topicUrl
和res.text
。
-
数据处理:
- 最终将所有话题的信息收集起来并打印出来。
通过这种方式,可以有效地处理多个异步请求,并在所有请求完成后进行统一的数据处理。
就是普通变量的意思
就是就地创建了一个数组,里面有两个值分别是 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]
对通过回调函数进行处理,提取所需的信息(如标题、评论等)。