Reputation: 60027
I have a promise chain that requests an RSS URL, parses it for links, then needs to request each link. The first part works great. However I'm having trouble working out how to "insert the promises" that request each link that has been parsed.
I started by generating a simple array of link URLs (preferred method) but couldn't make that work. The code now generates an array of promises to request each URL but I don't know how to make that work either. Perhaps I need to use Q.all() but that seems to be for predetermined functions?
requestRss(rssSourceUrl)
.then(function(links) {
// ???
})
.catch(function(error) {
console.log(error);
})
.done();
function requestRss(url) {
var deferred = q.defer();
request(url, function(err, resp, body) {
if (err || resp.statusCode !== 200) {
deferred.reject(new Error(resp.statusCode + ' ' + err + ' ' + body));
} else {
$ = cheerio.load(body);
var linkRegex = /<link>([^<$]+)/gim;
var someLinks = new Array();
$('item').each(function() {
var match = linkRegex.exec($(this).html());
if (match) {
var link = match[1];
someLinks.push(
function() { requestSomeLink(link); }
);
}
});
deferred.resolve(someLinks);
}
});
return deferred.promise;
}
function requestSomeLink(url) {
var deferred = q.defer();
request(url, function(err, resp, body) {
if (err || resp.statusCode !== 200) {
deferred.reject(new Error(resp.statusCode + ' ' + err + ' ' + body));
} else {
$ = cheerio.load(body);
deferred.resolve(body);
}
});
return deferred.promise;
}
Upvotes: 1
Views: 1551
Reputation: 664528
The code now generates an array of promises to request each URL
Actually it's an array of function which would each yield a promise for an url request when called. I think you should simply make it an array of links (strings), nothing more - what happens with them is to be determined in another function. So
function requestLinksFromRss(url) {
…
if (match)
someLinks.push(match[1]);
…
return deferred.promise;
}
Perhaps I need to use Q.all() but that seems to be for predetermined functions?
I don't see what you mean by "predetermined functions". Q.all()
just takes an array of promises as its argument. That's what we have here.
requestLinksFromRss(rssSourceUrl).then(function(links) {
var promiseArr = links.map(requestSomeLink); // or a loop if you want
return Q.all(promiseArr);
}).then(function(ressources) {
// now you have an array of request bodies.
// Do something with them.
}).catch(console.log.bind(console)).done();
Upvotes: 2
Reputation: 7292
You are not generating an "array of promises", but an array of functions that will ultimately return a promise. Where do you call those functions?
Let's say you go back to returning an array of links, and still have your requestSomeLink(url) function.
requestRss(rssSourceUrl)
.then(function(links) {
var index;
for (index = 0; index < links.length; index++) {
requestSomeLink(links[index]).then(function(data) {
// do something with data
}
}
})
Upvotes: 1