【发布时间】:2016-02-12 13:25:33
【问题描述】:
我有一个这样的页面:
<html>
<body>
<table>
<thead>
<tr>
<th>Link</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://www.google.com">Google</a></td><td>Search engine</td>
</tr>
<tr>
<td><a href="https://github.com">Github</a></td><td>Code management</td>
</tr>
</tbody>
</table>
</body>
</html>
我想解析表格的每一行并点击每个链接(以获取 HTML 的页面标题)来创建一个像这样的网站数组:
[ { name: 'Google',
title: 'Google',
descr: 'Search engine' },
{ name: 'Github',
title: 'GitHub · Where software is built',
descr: 'Code management' } ]
我认为这是开始学习使用 Promises 和 Q 库的一个很好的例子,但我没有掌握 Promises 的工作原理。 在我写的代码下面:
var request = require('request');
var cheerio = require('cheerio');
var Q = require('q');
var sites = [];
var loadPage = function(url){
var deferred = Q.defer();
request(url, function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
deferred.resolve($);
} else {
deferred.reject(new Error(error));
}
});
return deferred.promise;
}
var parseRows = function($){
var promises = [];
$("tbody tr").each(function(){
var $cells = $('td', this);
var $firstC = $cells.eq(0);
var name = $firstC.text();
var link = $firstC.find('a').attr('href');
var descr = $cells.eq(1).text();
promises.push(Q.fcall(function () {
var site = {name: name, descr: descr};
loadPage(link).then(function($){
var title = $("title").text();
console.log(title);
// here I don't know how to set the title
// as obj's attribute
});
return site;
}));
});
return Q.all(promises);
}
var displayTitles = function(res){
for (var i = 0, len = res.length; i < len; i++) {
var obj = res[i];
}
return Q.fcall(function () {
return sites;
});
}
loadPage('http://127.0.0.1/sample.html')
.then(parseRows)
.then(displayTitles)
.done();
我对 loadPage 函数很满意,但我被 parseRows 卡住了,因为我无法将标题设置为“站点”对象的属性。此外,displayTitles 最初是为了处理获取页面标题所需的逻辑而开发的,但现在几乎没用了。
如何修改上面的代码,以便以更干净和可读的方式获得所需的数组作为输出?
【问题讨论】:
-
这个问题似乎跑题了,因为它属于Code Review。
-
呃,我可能错了;你能用一个独立的例子把它清理成一个问题陈述吗?你这里有很多东西。
标签: javascript promise q