在javascript中循环异步的正确方法

时间:2016-09-28 12:24:38

标签: javascript async.js

我想知道这样做的正确方法是什么?

while(newList.length < 10){
            async.series([
                function(callback){         
                    async.eachSeries(rest,function(id,next){
                        if(getDistance(myLoc,id) < 5){
                            newList.push(id);
                        }
                        next();
                    });
                    callback();
                },
                function(callback){
                    var size = 10 - newList.length
                    rest = getPlaces()
                    callback();
                }], function(err,results){
                    if(err) console.log('error occured in : ' + err);
                });
        }
每次运行都会有10个新的地方填充休息,而asyc过程的第一步是找出10个地方的距离是否在5公里以内,如果它在5公里以内,那么它会被添加到newList,如果没有,那么我们将再做一次循环,直到它找到10个距离在5km以内的地方

虽然我的想法是重新迭代,直到我的newList被填充10(距离<10 km的地方),当我尝试运行它时,它只重复一次所有并且不会循环第二次运行。

3 个答案:

答案 0 :(得分:1)

使用async而不是常规while:

var newList = [];
async.whilst(
    function(){ return newList.length < 10;},
    function(done) {
        async.series([
           function(callback){  
               var size = 10 - newList.length
               rest = getPlaces()
               callback();       
           },
           function(callback){
               async.eachSeries(rest,function(id,next){
                   if(getDistance(myLoc,id) < 5){
                        newList.push(id);
                   }
                   next();
               });
               callback();
           }], 
           function(err,results){
               if(err) console.log('error occured in : ' + err);
               done(err, newList);
           };    
    },
    function(results) {
        // New list has been filled
    }
})

答案 1 :(得分:1)

好的,所以你在这里有几个问题 让我们从这开始:

function(callback){         
    async.eachSeries(rest,function(id,next){
        if(getDistance(myLoc,id) < 5){
            newList.push(id);
        }
        next();
    });
    callback();
}

你不是在等eachSeries的输出,你正在启动它,并立即回电。
该功能将独立填写您的newList,也许会立即填写,可能会稍有延迟;你无法知道,因为你马上回电 你也没有在这里使用series获得任何东西,因为它应该在前一个函数完成后运行每个函数。
您的代码最终可能会像这样工作:

  • 启动async.series
  • 运行第一个功能
  • 该函数以async.eachSeries
  • 开头
  • 该函数回调
  • 第二个功能启动,newList仍未填充
  • 第二个功能结束
  • 循环结束
  • newList 仍然未填写

除此之外,您的while功能也不必等待任何事情,它会一次又一次地盲目地运行async.series,直到您的newList被填满,可能占用大量资源。 您可以使用async.whilst之类的功能,例如:

async.whilst(
    function() { return newList.length < 10; },
    function(callback) {
        ...
    }, function(err, results) {
        console.log('loop has ended')
    }
)

此外,您应该使用series的回调来生成结果数组,并在循环结束时处理它们,而不是让函数随机且不可预测地填充内容。
例如:

function(callback){
    var list = []
    async.eachSeries(rest,function(id,next){
        if(getDistance(myLoc,id) < 5){
            list.push(id);
        }
        next();
    }, function(err) {
        callback(err, list);
    });
}

我希望这可以解释你的问题。

答案 2 :(得分:0)

我的建议是在while作用域之外有一个布尔变量,默认为true,当async函数用10个元素填充列表时,它被设置为false。希望有所帮助。