Javascript异步数组循环
我正在为一个运行在NodeJS上的游戏编写一个bot代码,这个函数应该做的是循环遍历一个向量数组,然后让bot转到每个向量 但是,它实际上是在告诉机器人同时运行到所有向量,这样它会突然出现,然后运行到数组中的最后一个向量: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
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吗?我不能在你完成后编辑它。