【发布时间】:2017-09-07 03:59:55
【问题描述】:
我正在学习如何使用 Promise。我有以下函数将“i”个 xkcd 漫画标题作为 Promise 返回:
var xkcd = function(i) {
return new Promise(
function(resolve, reject) {
var tempurl = 'https://www.xkcd.com/' + i;
request(tempurl, function(error, response, body) {
if (error) reject(error);
var $ = cheerio.load(body);
resolve($('title').text() + '\n');
});
});
};
如果我想获得前 4 个标题,我会这样链接我的 .then():
var result = '';
xkcd(1)
.then(fullfilled => {
result += fullfilled;
})
.then(() => xkcd(2))
.then(fullfilled => {
result += fullfilled;
})
.then(() => xkcd(3))
.then(fullfilled => {
result += fullfilled;
})
.then(() => xkcd(4))
.then(fullfilled => {
result += fullfilled;
console.log(result);
});
有没有更优雅的方法来做到这一点而无需链接这么多“then”?假设我想获得前 50 个漫画标题,我将不得不链接很多“then”。
我可以在不使用 Promises 的情况下使用递归回调来做到这一点:
function getXKCD(n) {
var i = 1;
(function getURL(i){
var tempurl = 'https://www.xkcd.com/' + i;
request(tempurl, function(error, response, body) {
if (error) console.log('error: ' + error);
var $ = cheerio.load(body);
//prints the title of the xkcd comic
console.log($('title').text() + '\n');
i++;
if (i <= n) getURL(i);
});
})(i);
}
getXKCD(4);
但我很想知道我是否可以对 Promises 做同样的事情。谢谢。
【问题讨论】:
-
看
Promise.all -
问题是您需要顺序接收文章还是一次性接收所有文章?
-
另外,您不必将
result += fullfilled;放在它自己的.then()中。您可以在同一.then()中调用下一个函数。用这种方式剪掉几乎一半。但是,如果这些不必连续运行,那么您可以一次运行它们并使用Promise.all()收集所有结果。 -
@zzzzBov 是的,看起来 Promise.all 将能够做我想做的事,谢谢。
-
顺便说一句,XKCD has a JSON API。不需要 Cheerio :-)
标签: javascript node.js promise cheerio