我试图从一些网址获取资源,该资源被分隔为多个页面,页面数量超过500,但资源的顺序必须得到保证,所以我决定使用Async模块。
function getData(page, callback){
var url = "http://someurl.com/document?page="+page;
// get data from the url ...
// when success,
callback();
};
所以,上面的函数是从某个url获取资源,我必须多次迭代这个函数,但我不知道如何用异步瀑布迭代这个函数。我应该推动进行迭代?
async.waterfall([
// page 1
function(callback){
getData(1, function(){
callback(null);
});
},
// page 2
function(callback){
getData(2, function(){
callback(null);
});
},
// page 3, 4, 5..... 100, ... 500
],function(err, result){
if(err) return next();
console.log('finish !');
});
答案 0 :(得分:2)
为什么不使用Promises:
function getData(page, callback){
var url = "http://someurl.com/document?page="+page;
// var request = call to get data from the url ...
return request;
};
var promises = [];
for (var page = 1; page < totalPages; page++) {
promises.push(getData(page));
}
Promise.all(promises).then(function (listOfResults) {
// Do callback here
});
确保发送get请求的方法返回一个promise。如果没有,你可以使用这样的函数:
function usesCallback(data, callback) {
// Do something with data
callback();
}
function makePromise(data) {
return new Promise(function (resolve, reject) {
usesCallback(data, resolve);
});
}
Here是关于Promises的更多信息
答案 1 :(得分:1)
如果您确实想使用async
,async.map()
和async.mapLimit()
是更好的选择,因为它们将iteratee
并行应用于每个项目,并保证结果数组为与原始集合的顺序相同。
async.mapLimit(_.range(1, 500), 10, getData, function (err, results) {
// do something with results
});
上面的代码意味着从第1页到第500页获取数据,一次不超过10个异步操作。
_.range(1, 500)
是来自underscore
的函数,用于生成数组[1, 2, 3, ..., 500]
。如果您不想在项目中使用underscore
,则可以简单地重写它,例如:
function range(lower, upper) {
return Array.apply(null, Array(upper - lower + 1))
.map(function (_, i) { return lower + i; });
}
答案 2 :(得分:0)
您可以为此check here使用async的,。