2016-08-02 72 views
0

我想从某些URL获取资源,该资源被分隔为多个页面,页面数量超过500,但资源的顺序必须得到保证,所以我决定使用Async模块。在Node.js中使用异步瀑布功能迭代

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 !'); 
}); 
+1

我甚至不会使用'for',使用递归。 –

回答

2

你为什么不使用承诺:

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请求的方法返回一个承诺。如果没有,你可以使用这样的功能:

function usesCallback(data, callback) { 
    // Do something with data 
    callback(); 
} 

function makePromise(data) { 
    return new Promise(function (resolve, reject) { 
     usesCallback(data, resolve); 
    }); 
} 

Here是承诺

+0

承诺对此不够好。承诺仅实现'promise.all'作为等同于'async.parallel'的流控制方法。只有这一点。另一方面,async.js库提供了许多其他算法来处理异步函数:parallel,series,waterfall,while(while),during,until等。如果您更喜欢promise模式,那么需要async.js的promisified版本称为async-q – slebetman

0

一些更多的信息,您可以使用异步的,而check here

1

如果你想使用asyncasync.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; }); 
}