在javascript中对代码段进行排队?
我需要对代码片段进行排队,并在给定的时间(每秒一次)执行它们。这些片段实际上是玩家的动作,如跳跃()、攻击()、行走('left')等 当用户按下某个键时,我需要将其操作排队,并每秒执行一次所有操作 目前,我的方法是将每个代码段添加到一个数组中,并使用eval()对其进行循环。这是我的代码:在javascript中对代码段进行排队?,javascript,queue,Javascript,Queue,我需要对代码片段进行排队,并在给定的时间(每秒一次)执行它们。这些片段实际上是玩家的动作,如跳跃()、攻击()、行走('left')等 当用户按下某个键时,我需要将其操作排队,并每秒执行一次所有操作 目前,我的方法是将每个代码段添加到一个数组中,并使用eval()对其进行循环。这是我的代码: var queue = []; // On player or AI action queue.push('attack()'); // Could be walk('left'), jump() etc
var queue = [];
// On player or AI action
queue.push('attack()'); // Could be walk('left'), jump() etc.
// On new frame
for(var i=0;i<queue.length;i++){
eval(queue[i]);
}
queue = [];
var队列=[];
//论玩家或人工智能动作
queue.push('attack()');//可能是步行('left')、跳跃()等。
//论新框架
对于(var i=0;i这是可怕的-eval
是邪恶的。相反,使用:
这是一般情况,但在这种情况下可以简化:function(){attack();}
是一种更复杂、更慢的编写attack
的方法,因此queue.push(attack)
也可以工作(如果您在可访问的地方定义了function attack(){…}
)。显然,如果您的函数采用参数(或者更确切地说,如果每个函数采用不同的参数;您可以在调用(thisobj,param)
调用中提供统一的参数列表),则您不能这样做
为您的附加查询编辑:
在您编写的代码中,这应该已将变量捕获到闭包中;如果您更改变量,则该值将是您在执行它时得到的值。如果您得到了未定义的,我猜您稍后在某处执行了closerEnemy=undefined
。例如,当人们试图将单击处理程序绑定到循环中的多个元素,并在处理程序中使用循环计数器-处理程序捕获计数器而不是其值,并始终在以后计算元素数(循环完成时留下的最后一个值)
要捕获值而不是变量,请使用以下技巧:
(function(capturedCloserEnemy) {
queue.push(function() {
attack(capturedCloserEnemy);
});
})(closerEnemy);
(变量的名称不同只是为了可读性;它们的名称可以相同,这并不重要,因为阴影。)这很可怕-eval
是邪恶的。相反,使用:
这是一般情况,但在这种情况下可以简化:function(){attack();}
是一种更复杂、更慢的编写attack
的方法,因此queue.push(attack)
也可以工作(如果您在可访问的地方定义了function attack(){…}
)。显然,如果您的函数采用参数(或者更确切地说,如果每个函数采用不同的参数;您可以在调用(thisobj,param)
调用中提供统一的参数列表),则您不能这样做
为您的附加查询编辑:
在您编写的代码中,这应该已将变量捕获到闭包中;如果您更改变量,则该值将是您在执行它时得到的值。如果您得到了未定义的,我猜您稍后在某处执行了closerEnemy=undefined
。例如,当人们试图将单击处理程序绑定到循环中的多个元素,并在处理程序中使用循环计数器-处理程序捕获计数器而不是其值,并始终在以后计算元素数(循环完成时留下的最后一个值)
要捕获值而不是变量,请使用以下技巧:
(function(capturedCloserEnemy) {
queue.push(function() {
attack(capturedCloserEnemy);
});
})(closerEnemy);
(变量的名称不同只是为了可读性;它们的名称可以相同,这并不重要,因为阴影。)您的方法的问题是:
您正在使用eval
您已经听说过使用eval的风险。如果没有,请检查
您正在使用循环
使用循环时,JavaScript会尽可能快地完成循环。这将导致UI中出现阻塞。这也意味着,当您以这种方式开始循环时,您的动画将仅在队列中的第一个动画时移动、冻结,并在最后一个动画时结束
为了解决这两个问题,为什么不将对要执行的函数的引用推送到队列中。此外,为了防止UI阻塞,请改用计时器:
var queue = [];
//actions as functions
function attack(params){...}
function block(params){...}
function walk(params){...}
//our animation timer
var animationTimer = setInterval(function(){
//remove the action from the queue and execute
var nextAction = queue.shift();
//if we shifted something, execute
if(nextAction){
nextAction.call();
}
},1000);
//to insert into the queue, push the reference of the function instead.
queue.push(attack);
您的方法的问题在于:
您正在使用eval
您已经听说过使用eval的风险。如果没有,请检查
您正在使用循环
使用循环时,JavaScript会尽可能快地完成循环。这将导致UI中出现阻塞。这也意味着,当您以这种方式开始循环时,您的动画将仅在队列中的第一个动画时移动、冻结,并在最后一个动画时结束
为了解决这两个问题,为什么不将对要执行的函数的引用推送到队列中。此外,为了防止UI阻塞,请改用计时器:
var queue = [];
//actions as functions
function attack(params){...}
function block(params){...}
function walk(params){...}
//our animation timer
var animationTimer = setInterval(function(){
//remove the action from the queue and execute
var nextAction = queue.shift();
//if we shifted something, execute
if(nextAction){
nextAction.call();
}
},1000);
//to insert into the queue, push the reference of the function instead.
queue.push(attack);
以这种方式使用eval
并没有实际的“风险”,但这当然是错误的。我知道了,但当我想用参数(如attack('up'))将函数排队时会发生什么?没有实际的“风险”以这种方式使用eval
,但这当然是错误的。我知道了,但当我想用参数(如攻击('up')对函数进行排队时会发生什么?这非常有效,我已经为玩家操作实现了。只是问一个问题,当存储在变量中时,如何将值传递给参数?例如:closerEnemy=1;queue.push(函数(){attack(closerEnemy);})
。稍后调用函数而不是简单地传递1时,它会检查未定义的closerEnemy。@Liso22:更新了您进一步问题的答案。这非常有效。我已经为玩家操作实现了。只是一个问题,当存储在变量中时,如何将值传递给参数?例如:closerEnemy=1;queue.push(function(){attack(closerEnemy);});
。稍后调用该函数而不是简单地传递1时,它会检查未定义的closerEnemy。@Liso22:更新了对进一步问题的回答