运行 setTimeout 方法时 Javascript 堆栈溢出 +传递变量
我知道我遇到的问题是什么,我只是很难找到解决方法。我想知道是否有人经历过类似的事情,以及他们实施了什么样的解决方案。
我有一个待修复的列表系统,并且我想要迟到的以黑色和红色闪烁的修复。此列表中可能有多个维修已晚。
这是我的函数:
function setblink(id) {
var elm = document.getElementById(id);
if (elm.color == "red"){
elm.color = "black";
}
else{
elm.color = "red";
}
setTimeout(setblink(id),500);
}
我有一个包含需要闪烁的项目的“id”数组,称为repsToBlink。
我通过运行以下代码来为每次修复运行设置的闪烁间隔,这将它们置于递归循环中。
for(var x in repsToBlink){
setTimeout(setblink(repsToBlink[x]),500);
}
我怎样才能让这段代码做同样的事情,而不导致堆栈溢出?
谢谢!
I know what the problem I am experiencing is, I am just having a hard time finding a work around. I was wondering if anyone had experienced something like this, and what kinda of solution they implemented.
I have a list system with pending repairs, and I want repairs that are late to blink black and red. It's possible that there are multiple repairs in this list that are late.
here is my function:
function setblink(id) {
var elm = document.getElementById(id);
if (elm.color == "red"){
elm.color = "black";
}
else{
elm.color = "red";
}
setTimeout(setblink(id),500);
}
I have an array of "id's" for the items that need to be blinking called repsToBlink.
I get the set blink intervals running for each of these repairs by running the following code, which puts them in a recursive loop.
for(var x in repsToBlink){
setTimeout(setblink(repsToBlink[x]),500);
}
How can I get this code doing the same thing, without causing a stack overflow?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要将 setTimeout 从更改
为:
setTimeout()
期望将函数作为参数传递,而您正在传递函数的结果。You need to change your setTimeout from
to:
setTimeout()
expects a function to be passed as parameter, whereas you are passing the result of the function.setblink(id)
立即调用该函数。堆栈溢出是立即执行而不是延迟执行的症状,因为 setTimeout 会安排稍后执行,因此将来的调用不会推送到当前调用堆栈上。由于
setblink
需要一个参数,因此将其包装在 nullary 用于延迟评估的匿名函数。该代码需要更多改进。
如果
repsToBlink
是一个数组,您应该循环遍历repsToBlink< 的整数索引
/code> (
for (...;...;...)
),而不是属性 (for ... in
)。但是,如果您要使用带有 ids 和索引(而不是值)的对象,则for ... in
会更合适。上面的代码为每个
id
触发一个单独的计时器(这可能会压垮浏览器)。通过将循环移动到一个函数(该函数成为唯一要调度的函数),只需要一个计时器。由于您定期运行一个函数,因此
setInterval
更合适。每当您从
repsToBlink
中删除 id 时,请检查是否还有剩余;如果没有,则取消间隔。setblink(id)
calls the function immediately. A stack overflow is a symptom of immediate, rather than delayed, execution sincesetTimeout
schedules execution for later so the future invocation won't get pushed on the current call stack.Since
setblink
takes an argument, wrap it in a nullary anonymous function for lazy evaluation.The code calls for more improvements.
If
repsToBlink
is an array, you should loop over the integer indices ofrepsToBlink
(for (...;...;...)
), not the properties (for ... in
). However, if instead you were to use an object with the ids an indices (rather than values),for ... in
would be appropriate.The above fires a separate timer for each
id
(which could overwhelm the browser). By moving the loop to a function, which becomes the only function to be scheduled, only a single timer is required.Since you're running a function periodically,
setInterval
is more appropriate.Whenever you remove and id from
repsToBlink
, check whether there are any remaining; if not, cancel the interval.您的问题是在全局上下文中调用
setTimeout
。这样,您就可以立即调用该函数。解释器在到达以下代码时:
setTimeout(setblink(id),500);
立即调用
setblink
函数,假设该函数的返回值是超时应该调用。这会导致堆栈溢出,因为这是一个递归函数。要解决此问题,请将 setTimeout 要调用的函数包装在
function(){}
内。Your problem is that
setTimeout
is being called in a global context. That, and you're instantly calling the function.The interpreter, when it gets to this code:
setTimeout(setblink(id),500);
is calling the
setblink
function immediately, assuming that that function's return value is what the timeout is supposed to call. This causes a stack overflow, because that is a recursive function.To fix, this, wrap the function that setTimeout is to call inside a
function(){}
.