简体   繁体   English

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

[英]Function iteration with Async waterfall in Node.js

I am trying to get resource from the some url, that resource is separated as multiple pages, the number of page is over 500, but the order of resource have to be guaranteed, so I decided to use Async module. 我试图从某个URL获取资源,该资源被分成多个页面,页面数超过500,但是必须保证资源的顺序,因此我决定使用Async模块。

function getData(page, callback){
    var url = "http://someurl.com/document?page="+page;
    // get data from the url ...
    // when success, 
    callback();
};

So, above function is get resource from some url, I have to iterate this function to many times, but I don't know how can I iterate this with async waterfall. 因此,上面的函数是从某个URL获取资源,我必须将该函数进行多次迭代,但是我不知道如何用异步瀑布对该函数进行迭代。 What point I should push the for iteration? 什么时候我应该推迭代

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

Why don't you use Promises: 您为什么不使用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
});

Just make sure that your method of sending the get request returns a promise. 只要确保您发送get请求的方法返回一个诺言即可。 If not you can use a function like this: 如果没有,您可以使用如下函数:

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

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

Here is some more info on Promises 是有关Promises的更多信息

If you do want to use async , async.map() and async.mapLimit() are better choices since they apply the iteratee to each item in parallel and guarantee the results array to be in the same order as the original collection. 如果确实要使用async ,则async.map()async.mapLimit()是更好的选择,因为它们将iteratee并行应用于每个项目,并保证结果数组与原始集合的顺序相同。

async.mapLimit(_.range(1, 500), 10, getData, function (err, results) {
    // do something with results
});

The code above means to get data from page 1 to page 500, with no more than 10 async operations at a time. 上面的代码意味着从第1页到第500页获取数据,一次不超过10个异步操作。

_.range(1, 500) is a function from underscore to generate an array [1, 2, 3, ..., 500] . _.range(1, 500)underscore生成数组[1, 2, 3, ..., 500]的函数。 If you do not like to use underscore in your project, you can simply rewrite it such as: 如果您不喜欢在项目中使用underscore ,则可以简单地重写它,例如:

function range(lower, upper) {
    return Array.apply(null, Array(upper - lower + 1))
        .map(function (_, i) { return lower + i; });
}

您可以使用异步的,而在这里检查

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM