问题描述
在下面的代码中,我试图一次性发出多个(大约 10 个)HTTP 请求和 RSS 解析.
In the following code I am trying to make multiple (around 10) HTTP requests and RSS parses in one go.
我在需要访问和解析结果的 URI 数组上使用标准 forEach
构造.
I am using the standard forEach
construct on an array of URIs I need to access and parse the result of.
代码:
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
我知道在调用一次函数时我应该使用回调.然而,我能想到在这个例子中使用回调的唯一方法是调用一个函数,该函数计算它被调用的次数,并且只有当它被调用的次数与 feedsToFetch.length 相同时才会继续
看起来很笨拙.
I understand that when calling a function once I should be using a callback. However, the only way I can think of using a callback in this example would be to call a function which counts how many times it has been called and only continues when it has been called the same amount of times as feedsToFetch.length
which seems hacky.
所以我的问题是,在 node.js 中处理这种情况的最佳方法是什么.
最好没有任何形式的阻塞!(我仍然想要那种极快的速度).是承诺还是别的什么?
Preferably without any form of blocking! (I still want that blazing fast speed). Is it promises or something else?
谢谢,丹尼
推荐答案
HACK-FREE 解决方案
流行的 Promise 库为您提供了一个 .all()
方法用于这个确切的用例(等待一堆异步调用完成,然后做其他事情).它非常适合您的场景
The popular Promise libraries give you an .all()
method for this exact use case (waiting for a bunch of async calls to complete, then doing something else). It's the perfect match for your scenario
Bluebird 也有 .map()
,它可以接受一组值并使用它来启动 Promise 链.
Bluebird also has .map()
, which can take an array of values and use it to start a Promise chain.
这是一个使用 Bluebird .map()
的例子:
Here is an example using 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)...
}
另请注意,这里不需要使用闭包来累积结果.
Notice also that you don't need to use closure here to accumulate the results.
Bluebird API 文档 也写得很好,有很多的例子,所以它更容易拿起.
The Bluebird API Docs are really well written too, with lots of examples, so it makes it easier to pick up.
一旦我学会了 Promise 模式,它让生活变得更加轻松.我不能推荐它.
Once I learned Promise pattern, it made life so much easier. I can't recommend it enough.
此外,这是一篇很棒的文章 关于使用 Promise、async
模块等处理异步函数的不同方法
Also, here is a great article about different approaches to dealing with async functions using promises, the async
module, and others
希望这有帮助!
这篇关于Node.js:执行多个异步操作的最佳方式,然后做其他事情?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!