在Node.js中使用Async瀑布进行函数迭代

时间:2016-08-02 08:46:45

标签: javascript node.js asynchronous

我试图从一些网址获取资源,该资源被分隔为多个页面,页面数量超过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 !');
});

3 个答案:

答案 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)

如果您确实想使用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; });
}

答案 2 :(得分:0)

您可以为此check here使用async的