我为在NodeJS上运行的游戏制作机器人代码,这个函数应该做的是循环遍历一组向量,然后让机器人去每个向量。
然而,它实际上做的是告诉机器人同时运行所有向量,以便它出现然后运行到数组中的最后一个向量:
function digSchedule() {
var arrayLength = blocksToMine.length;
for (var i = 0; i < blocksToMine.length; i++) {
console.log(i);
scaffoldTo(blocksToMine[i]);
}
...
}
需要运行函数scaffoldTo()
,然后等待机器人执行上述函数,然后为阵列中的下一个元素运行它,但我无法弄清楚如何执行此操作。 / p>
答案 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!");
})