在下面的代码中,我试图一次性发出多个(大约10个)HTTP请求和RSS解析.
我在一个URI数组上使用标准的forEach构造,我需要访问并解析结果.
码:
var articles; FeedsToFetch.forEach(function (FeedUri) { Feed(FeedUri,function(err,FeedArticles) { if (err) { throw err; } else { articles = articles.concat(FeedArticles); } }); }); // Code I want to run once all FeedUris have been visited
我明白,当我应该使用回调时调用一个函数.但是,我能想到在这个例子中使用回调的唯一方法是调用一个函数,该函数计算它被调用的次数,并且仅在调用与FeedToFetch.length相同的次数时才继续调用,这看起来像hacky .
所以我的问题是,在node.js中处理这种情况的最佳方法是什么.
优选地,没有任何形式的阻塞! (我仍然希望速度超快).这是承诺还是其他什么?
谢谢,
丹尼
解决方法
无需解决方案
Promises to be included in next JavaScript version
流行的Promise库为这个确切的用例提供了一个.all()方法(等待一堆异步调用完成,然后做其他事情).这是您的场景的完美搭配
Bluebird还有.map(),它可以获取一组值并使用它来启动Promise链.
以下是使用Bluebird .map()的示例:
var Promise = require('bluebird'); var request = Promise.promisifyAll(require('request')); function processAllFeeds(FeedsToFetch) { return Promise.map(FeedsToFetch,function(Feed){ // I renamed your 'Feed' fn to 'processFeed' return processFeed(Feed) }) .then(function(articles){ // 'articles' is now an array w/ results of all 'processFeed' calls // do something with all the results... }) .catch(function(e){ // Feed server was down,etc }) } function processFeed(Feed) { // use the promisified version of 'get' return request.getAsync(Feed.url)... }
另请注意,您不需要在此处使用闭包来累积结果.
Bluebird API Docs也写得很好,有很多例子,所以它更容易上手.
一旦我学会了Promise模式,它就让生活变得如此简单.我不能推荐它.
此外,这里是a great article关于使用promises,异步模块和其他处理异步函数的不同方法
希望这可以帮助!