简体   繁体   English

为什么 setTimeout 不等待调用函数?

[英]Why doesn't setTimeout wait to call a function?

I want to create a simple game of sorts.我想创建一个简单的游戏。 I am trying to duplicate a div recursively after a few seconds.我试图在几秒钟后递归地复制一个 div。 After duplicated, it creates the new div with a new unique ID (ID+i).复制后,它会使用新的唯一 ID (ID+i) 创建新的 div。

The idea is that it keeps creating divs and the user has to click on them to remove them for as long as they can before it reaches the max (game over).这个想法是它会不断创建 div,并且用户必须尽可能长时间地单击它们以将其删除,然后才能达到最大值(游戏结束)。

It won't properly wait to create the divs.它不会正确等待创建 div。 I want to create new divs from the existing one every few seconds, but it either creates all 15 as soon as I run it or it only creates 1 and stops there.我想每隔几秒钟从现有的 div 创建一个新的 div,但它要么在我运行它时立即创建所有 15 个 div,要么只创建 1 个并在那里停止。

JSFIDDLE - https://jsfiddle.net/namelesshonor/msrkxq63/ JSFIDDLE - https://jsfiddle.net/namelesshonor/msrkxq63/

function spawnFly() {
if(x >= 15){
    alert("YOU LOST\n15 Flys have infested your screen!");
}
else if(x < 15) {   
    x++; // adds another fly to the counter 
    setTimeout(duplicate(), 2000); // spawns a new fly after a few secs
    animateDiv(); // animate the spawned fly
    spawnFly(); // called recursively until fly count is met
}   
};

function duplicate() {
var original = document.getElementById('fly'+i);
var clone = original.cloneNode(true);
clone.id = "fly" + i++;
clone.onclick = swat;
original.parentNode.appendChild(clone);
};

function animateDiv(){
var newq = makeNewPosition();
var oldq = $('.shoo').offset();
var speed = calcSpeed([oldq.top, oldq.left], newq);
$('.shoo').animate({ top: newq[0], left: newq[1] }, speed, function(){
  animateDiv();        
});
};

The argument to setTimeout should be the function pointer to duplicate , not the result of calling the duplicate function. setTimeout的参数应该是duplicate的函数指针,而不是调用duplicate函数的结果。

setTimeout(duplicate(), 2000);

should be应该

setTimeout(duplicate, 2000);

Also, you might be intending to call the spawnFly function in the timeout, not the duplicate function.此外,您可能打算在超时时调用spawnFly函数,而不是重复函数。 The duplicate function would then be called immediately to "spawn" a new fly.然后将立即调用重复函数以“产生”新的苍蝇。 Then in 2 seconds, the spawnFly function is called to duplicate another fly and queue spawnFly again.然后在 2 秒内,调用spawnFly函数duplicate另一只苍蝇并再次排队spawnFly The way you currently have it set up, the it immediately recurs into the spawnFly function, queuing up 15 flies to spawn in 2 seconds and immediately topping out the fly count ( x )您当前设置的方式,它立即递归到 spawnFly 函数中,在 2 秒内排队 15 只苍蝇产卵,并立即使苍蝇计数 ( x ) 达到顶峰

Also, you're your increment of i causes an off by 1 error such that you're always trying to assign the value of the next fly to original .此外,您的i增量会导致 off by 1 错误,因此您总是试图将 next fly 的值分配给original You should use pre-increment ( ++i ) instead of post-increment ( i++ ) to get your desired result您应该使用预增量( ++i )而不是后增量( i++ )来获得所需的结果

All changes applied: https://jsfiddle.net/msrkxq63/3/应用了所有更改: https : //jsfiddle.net/msrkxq63/3/

When you call setTimeout in your example, you're passing the result of duplicate() , not the function duplicate itself as the callback.当您在示例中调用setTimeout时,您传递的是duplicate()的结果,而不是函数duplicate自身duplicate为回调。 As duplicate does not return anything, setTimeout tries to call the function undefined .由于重复不返回任何内容, setTimeout尝试调用函数undefined You could either call it this way (as an anonymous callback):您可以这样称呼它(作为匿名回调):

setTimeout(function() { duplicate }, 2000)

or simply,或者干脆,

setTimeout(duplicate, 2000)

If you notice duplicate() in setTimeout(duplicate(),2000);如果您发现duplicate()setTimeout(duplicate(),2000); , ,
it's a function call.这是一个函数调用。
setTimeout 's first parameter is a function. setTimeout的第一个参数是一个函数。 If you pass duplicate() ,如果你通过duplicate()
it gets evaluated before the wait and looks for the return value and calls that.它在等待之前被评估并查找返回值并调用它。
Function or not, it waits after the function call and ends up doing nothing after函数与否,它函数调用之后等待,之后什么都不做
the wait.这段等待。 So we can say the flow is:所以我们可以说流程是:
1​. 1。 Callback = duplicate()回调 = duplicate() ( duplicate is called before wait) = <return value of duplicate > instead of the function duplicate itself. duplicate在等待之前调用) = < duplicate返回值> 而不是函数duplicate本身。
2. Milliseconds = 2000 . 2. 毫秒 = 2000
3. Call return value after 2 seconds. 3. 2 秒后调用返回值。
The correct code is:正确的代码是:
setTimeout(duplicate,2000)//Note that there are no brackets here

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM