如何在使用node.js Q链执行期间插入promise?

我有一个承诺链,请求一个RSS URL,parsing它的链接,然后需要请求每个链接。 第一部分很好。 然而,我有问题的工作如何“插入承诺”,要求每个链接已被parsing。

我开始通过生成一个简单的链接url(首选的方法),但无法做到这一点。 代码现在生成一个promise数组请求每个URL,但我不知道如何使这个工作。 也许我需要使用Q.all(),但似乎是预定义的function?

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

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

实际上,这是一个函数的数组,每次调用时都会产生url请求的承诺。 我想你应该简单地把它作为一个链接(string)的数组,只不过是在另一个函数中确定发生的事情。 所以

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

也许我需要使用Q.all(),但似乎是预定function?

我不明白“预定function”是什么意思。 Q.all()只需要一个promise数组作为参数。 这就是我们在这里。

 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(); 

你不是在生成一个“承诺数组”,而是一系列最终会返回承诺的函数。 你在哪里叫这些function?

假设你回头去返回一个链接数组,并且仍然有你的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 } } })