1

我有一个请求 RSS URL 的承诺链,解析它的链接,然后需要请求每个链接。第一部分效果很好。但是,我无法弄清楚如何“插入承诺”来请求每个已解析的链接。

我首先生成了一个简单的链接 URL 数组(首选方法),但无法实现。代码现在会生成一组请求来请求每个 URL,但我也不知道如何使其工作。也许我需要使用Q.all()但这似乎是用于预定功能?

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;
}
4

2 回答 2

2

代码现在生成一组 promise 来请求每个 URL

实际上,它是一个函数数组,每个函数在调用时都会产生一个对 url 请求的承诺。我认为您应该简单地将其设置为链接(字符串)数组,仅此而已-它们发生的情况将在另一个函数中确定。所以

function requestLinksFromRss(url) {
    …
                    if (match)
                        someLinks.push(match[1]);
    …
    return deferred.promise;
}

也许我需要使用 Q.all() 但这似乎是用于预定功能?

我不明白您所说的“预定功能”是什么意思。Q.all()只是将一系列承诺作为其参数。这就是我们在这里所拥有的。

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();
于 2013-07-18T21:30:34.477 回答
1

您不是在生成“承诺数组”,而是最终将返回承诺的函数数组。你在哪里调用这些函数?

假设您返回返回一个链接数组,并且仍然有您的 requestSomeLink(url) 函数。

requestRss(rssSourceUrl)
.then(function(links) { 
    var index;
    for (index = 0; index < links.length; index++) {
        requestSomeLink(links[index]).then(function(data) {
            // do something with data
        }
    }
})
于 2013-07-18T21:18:40.983 回答