Javascript循环遍历数组异步

时间:2017-07-07 22:13:54

标签: javascript arrays loops asynchronous

我为在NodeJS上运行的游戏制作机器人代码,这个函数应该做的是循环遍历一组向量,然后让机器人去每个向量。

然而,它实际上做的是告诉机器人同时运行所有向量,以便它出现然后运行到数组中的最后一个向量:

function digSchedule() {
    var arrayLength = blocksToMine.length;
    for (var i = 0; i < blocksToMine.length; i++) {
        console.log(i);
        scaffoldTo(blocksToMine[i]);
    }
    ...
}

需要运行函数scaffoldTo(),然后等待机器人执行上述函数,然后为阵列中的下一个元素运行它,但我无法弄清楚如何执行此操作。 / p>

6 个答案:

答案 0 :(得分:0)

这是ES2017 async functions的一个很好的用例。

请尝试以下方法:

async function digSchedule() {
    var arrayLength = blocksToMine.length;
    for (var i = 0; i < blocksToMine.length; i++) {
        console.log(i);
        await scaffoldTo(blocksToMine[i]);
    }
    ...
}

如果ES2017不可能,那么你最好的选择就是制作一个递归函数,只有在scaffoldTo的承诺得到解决时才会再次自我调用。

答案 1 :(得分:0)

有几种方法可以实现这一目标。第一个可能是通过“下一个要调用的函数”(可能是scaffoldTo())来传递回调。您可以使用.bind()创建迭代器索引i的引用。

或者,您可以设置Promise s的循环,根据定义,该循环具有.then()方法,该方法在解析承诺后执行。

最后,async / await模式类似于Promises,但有些模式更清晰,似乎赢得了Hype Wars:https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

回调(解决方案1)将在任何版本的JS中提供。承诺通常与库一起提供,并在ES6中具有本机支持。 Async / await是ES2017中的提案(?),通常得到很好的支持。

答案 2 :(得分:0)

这是你可以玩这个的另一种方式。这种方式更多地关注回调样式,尽管它假设你可以修改scaffoldTo函数,以及digSchedule所需的参数

function digSchedule(i, callback) {
   if(!i){
      i = 0;
   }
   if(i < blocksToMine.length){
      scaffoldTo(blocksToMine[i], digSchedule(i++, callback));
   }
   else{
     callback();
   }
}

然后在scaffold里面你需要这样的东西

function scaffoldTo(block, callback){
    //do what ever you need to have the bot go to the vector
    //after bot goes to vector call callback
    callback();
}

为了启动它,你只需要用这样的东西调用digSchedule:

digSchedule({null or 0}, function(){
   console.log("finished visiting vectors");
});

这确实改变了使用for循环的模式,但我认为这也是实现目标的有趣方式。

答案 3 :(得分:0)

使用Ben的答案,我能够学会如何做我想要的事情但是我也了解到这不会起作用;我必须通过代码支持我想要的功能本身。感谢您的支持! :)

答案 4 :(得分:0)

您可以使用async模块来实现此目的。或者,您可以尝试这样的事情

function forEachAsync(array, fun, cb) {
        var index = 0;
        if (index == array.length) {
                cb(null);
                return;
        }

        var next = function () {
                fun(array[index], function(err) {
                        if (err) {
                                cb(err);
                                return;
                        }
                        index++;
                        if (index < array.length) {
                                setImmediate(next);
                                return;
                        }

                        //We are done
                        cb(null);
                });
        };

        next();
}

forEachAsync([1,2,3,4,5], function(e, cb) {
        console.log(e);
        cb();
}, function(err) {
        console.log('done');
});

答案 5 :(得分:0)

这是我们在诺言的帮助下所做的事情。

let numbers = new Array(1,3,2,1);
function asyncFunction(number){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log("Number : ",number);
            return resolve();
        },number*1000);
    })
  
}
let promise = Promise.resolve();
// Here we are using forEach to chain promise one after another.
numbers.forEach(number=>{
    promise = promise.then(()=>{
        return asyncFunction(number);
    });
})
promise.then(()=>{
    console.log("Every thing is done!");
})