为什么 setTimeout 不等待调用函数?
Why doesn't setTimeout wait to call a function?
我想创建一个简单的游戏。我试图在几秒钟后递归地复制 div 。复制后,它会创建具有新的唯一 ID (ID+i) 的新 div。
想法是,它会不断创建 div,用户必须在达到最大值(游戏结束)之前尽可能长时间地点击它们以将其删除。
它不会正确地等待创建 divs。我想每隔几秒从现有的 div 中创建新的 divs,但它要么在我 运行 时立即创建所有 15 个,要么只创建 1 个并停在那里。
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();
});
};
setTimeout
的参数应该是指向duplicate
的函数指针,而不是调用duplicate
函数的结果。
setTimeout(duplicate(), 2000);
应该是
setTimeout(duplicate, 2000);
此外,您可能打算在超时时调用 spawnFly
函数,而不是重复函数。然后将立即调用复制函数以 "spawn" 一只新苍蝇。然后在 2 秒内,spawnFly
函数被调用到 duplicate
另一只 fly 并再次排队 spawnFly
。按照您目前的设置方式,它会立即返回到 spawnFly 函数中,在 2 秒内排队等待 15 只苍蝇产卵,并立即达到飞行计数 (x
)
此外,您的 i
增量会导致 off by 1 错误,因此您总是试图将下一次飞行的值分配给 original
。您应该使用预增量 (++i
) 而不是 post-增量 (i++
) 来获得您想要的结果
应用所有更改:
https://jsfiddle.net/msrkxq63/3/
当您在您的示例中调用 setTimeout
时,您传递的是 duplicate()
的结果,而不是函数 duplicate
本身作为回调。由于 duplicate 没有 return 任何东西,setTimeout
尝试调用函数 undefined
。您可以这样称呼它(作为匿名回调):
setTimeout(function() { duplicate }, 2000)
或者简单地说,
setTimeout(duplicate, 2000)
如果您注意到 setTimeout(duplicate(),2000);
中的 duplicate()
,
这是一个函数调用。
setTimeout
的第一个参数是一个函数。
如果您通过 duplicate()
,
它在等待之前得到评估并查找 return 值并调用它。
功能与否,它在 函数调用后等待,并在
等待后什么也不做。
所以我们可以说流程是:
1 .回调 = duplicate()
(duplicate
在等待之前调用) = 而不是函数 duplicate
本身。
2。毫秒 = 2000
。
3。 2 秒后调用 return 值。
正确的代码是:
setTimeout(duplicate,2000)//Note that there are no brackets here
我想创建一个简单的游戏。我试图在几秒钟后递归地复制 div 。复制后,它会创建具有新的唯一 ID (ID+i) 的新 div。
想法是,它会不断创建 div,用户必须在达到最大值(游戏结束)之前尽可能长时间地点击它们以将其删除。
它不会正确地等待创建 divs。我想每隔几秒从现有的 div 中创建新的 divs,但它要么在我 运行 时立即创建所有 15 个,要么只创建 1 个并停在那里。
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();
});
};
setTimeout
的参数应该是指向duplicate
的函数指针,而不是调用duplicate
函数的结果。
setTimeout(duplicate(), 2000);
应该是
setTimeout(duplicate, 2000);
此外,您可能打算在超时时调用 spawnFly
函数,而不是重复函数。然后将立即调用复制函数以 "spawn" 一只新苍蝇。然后在 2 秒内,spawnFly
函数被调用到 duplicate
另一只 fly 并再次排队 spawnFly
。按照您目前的设置方式,它会立即返回到 spawnFly 函数中,在 2 秒内排队等待 15 只苍蝇产卵,并立即达到飞行计数 (x
)
此外,您的 i
增量会导致 off by 1 错误,因此您总是试图将下一次飞行的值分配给 original
。您应该使用预增量 (++i
) 而不是 post-增量 (i++
) 来获得您想要的结果
应用所有更改: https://jsfiddle.net/msrkxq63/3/
当您在您的示例中调用 setTimeout
时,您传递的是 duplicate()
的结果,而不是函数 duplicate
本身作为回调。由于 duplicate 没有 return 任何东西,setTimeout
尝试调用函数 undefined
。您可以这样称呼它(作为匿名回调):
setTimeout(function() { duplicate }, 2000)
或者简单地说,
setTimeout(duplicate, 2000)
如果您注意到 setTimeout(duplicate(),2000);
中的 duplicate()
,
这是一个函数调用。
setTimeout
的第一个参数是一个函数。
如果您通过 duplicate()
,
它在等待之前得到评估并查找 return 值并调用它。
功能与否,它在 函数调用后等待,并在
等待后什么也不做。
所以我们可以说流程是:
1 .回调 = duplicate()
(duplicate
在等待之前调用) = duplicate
本身。
2。毫秒 = 2000
。
3。 2 秒后调用 return 值。
正确的代码是:
setTimeout(duplicate,2000)//Note that there are no brackets here