Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript异步数组循环_Javascript_Arrays_Loops_Asynchronous - Fatal编程技术网

Javascript异步数组循环

Javascript异步数组循环,javascript,arrays,loops,asynchronous,Javascript,Arrays,Loops,Asynchronous,我正在为一个运行在NodeJS上的游戏编写一个bot代码,这个函数应该做的是循环遍历一个向量数组,然后让bot转到每个向量 但是,它实际上是在告诉机器人同时运行到所有向量,这样它会突然出现,然后运行到数组中的最后一个向量: function digSchedule() { var arrayLength = blocksToMine.length; for (var i = 0; i < blocksToMine.length; i++) { console

我正在为一个运行在NodeJS上的游戏编写一个bot代码,这个函数应该做的是循环遍历一个向量数组,然后让bot转到每个向量

但是,它实际上是在告诉机器人同时运行到所有向量,这样它会突然出现,然后运行到数组中的最后一个向量:

function digSchedule() {
    var arrayLength = blocksToMine.length;
    for (var i = 0; i < blocksToMine.length; i++) {
        console.log(i);
        scaffoldTo(blocksToMine[i]);
    }
    ...
}
函数digSchedule(){
var arrayLength=块的最小长度;
对于(变量i=0;i

需要运行函数
scaffoldTo()
,然后等待bot执行所述函数,然后为数组中的下一个元素运行它,但我不知道如何执行。

这是ES2017的一个很好的用例

请尝试以下操作:

async function digSchedule() {
    var arrayLength = blocksToMine.length;
    for (var i = 0; i < blocksToMine.length; i++) {
        console.log(i);
        await scaffoldTo(blocksToMine[i]);
    }
    ...
}
异步函数digSchedule(){ var arrayLength=块的最小长度; 对于(变量i=0;i
如果ES2017是不可能的,那么最好的选择是创建一个递归函数,该函数只有在
scaffoldTo
的承诺得到解决时才会再次调用自身。

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

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

最后,
异步
/
等待
模式与承诺类似,但一些人发现它更清晰,似乎正在赢得宣传战:


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

这里有另一种方法可以使用它。这种方式更多地关注回调样式,尽管它假定您可以修改scaffoldTo函数以及digSchedule所需的参数

function digSchedule(i, callback) {
   if(!i){
      i = 0;
   }
   if(i < blocksToMine.length){
      scaffoldTo(blocksToMine[i], digSchedule(i++, callback));
   }
   else{
     callback();
   }
}
为了开始这一切,您只需要调用digSchedule,如下所示:

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

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

使用Ben的答案,我能够学会如何做我想做的事情,但我也学会了这是行不通的;我必须对我想要的函数本身进行检查和编码支持。谢谢你的支持!:)

您可以使用模块来实现这一点。或者,你可以试试这样的东西

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();
}
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');
});
函数forEachAsync(数组、fun、cb){ var指数=0; if(index==array.length){ cb(空); 返回; } var next=函数(){ fun(数组[索引],函数(err){ 如果(错误){ cb(err); 返回; } 索引++; if(索引<数组长度){ 立即(下一个); 返回; } //我们完了 cb(空); }); }; next(); } forEachAsync([1,2,3,4,5],函数(e,cb){ 控制台日志(e); cb(); },函数(err){ console.log('done'); });
以下是我们在承诺的帮助下的做法

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

嗨,D,欢迎来到SO!带示例代码的格式良好的问题-喜欢:)阅读异步Promise忘了提及我在nodeJS上运行此操作它不允许我编辑操作idkI假设
scaffoldTo()
是异步的?它是如何实施的?循环如何确定函数何时“完成”?@ScottStensland-与同步承诺相反:我在NodeJS上,我得到了这个错误:SyntaxError:意外的令牌函数sync函数是ES2017,而不是ES6。你需要Node 7.6.0或更高版本。递归是不必要的
async/await
只是承诺的语法甜点。您可以使用连续传递回调或一系列承诺来获得结果。您可以编辑帖子以包含我正在使用NodeJS吗?我不能在你完成后编辑它。