Javascript 为什么';我的setTimeout回调没有被调用吗?
我正忙着制作一款闪卡游戏。我想给用户一个可视的倒计时,然后屏幕上就会闪现一张卡片。我的倒计时脚本如下所示:Javascript 为什么';我的setTimeout回调没有被调用吗?,javascript,jquery,timer,Javascript,Jquery,Timer,我正忙着制作一款闪卡游戏。我想给用户一个可视的倒计时,然后屏幕上就会闪现一张卡片。我的倒计时脚本如下所示: let downSeconds = 5; while (downSeconds > 0) { setTimeout(function() { $("#timerDisplay").text = downSeconds; downSeconds--; }, 1000); } $(".detail-card").removeClass("
let downSeconds = 5;
while (downSeconds > 0) {
setTimeout(function() {
$("#timerDisplay").text = downSeconds;
downSeconds--;
}, 1000);
}
$(".detail-card").removeClass("hidden");
如果我不想要更新的秒数,我会使用5000ms的“设置超时”。我之前尝试过使用设置间隔
,延迟为1000毫秒,因此每次都会更新秒数
现在,如果我在setTimeOut
回调的任一行上放置一个断点,并且只有在那里,调用setTimeOut
时不会发生任何事情,因此秒显示永远不会更新,我处于无限循环中,因为downSeconds--代码>从不被调用,因此downSeconds
始终保持值5
我做错了什么?setTimeout稍后运行代码,而while循环“现在”运行。你不能成功地将两者结合起来。。因此,您必须以不同的方式编写代码,类似这样的方式应该可以工作:
let downSeconds = 5;
function doCountDown() {
downSeconds--;
$("#timerDisplay").text = downSeconds;
if (downSeconds > 0) {
setTimeout(doCountDown, 1000);
} else {
$(".detail-card").removeClass("hidden");
}
}
setTimeout(doCountDown, 1000);
您可以使用ES7并等待循环一秒钟:
const time = ms => new Promise(res => setTimeout(res,ms));
(async function(){
let downSeconds = 5;
while (downSeconds > 0) {
await time(1000);
$("#timerDisplay").text = downSeconds;
downSeconds--;
}
$(".detail-card").removeClass("hidden");
})()
setTimeout
调用是异步的,
因此,当第一次调用setTimeout
计划的1000毫秒过去时,
while循环将执行其主体数千次,
每次使用setTimeout
调度新作业时,
导致JavaScript引擎的大量调度工作。
发动机太忙,无法执行该功能,
而且情况越来越糟,
随着循环不断运行,并不断安排越来越多的时间。
我希望您的执行环境变得无响应,无法取得进展,无法实际调用计划的第一个函数
使用setInterval
和clearInterval
代替,例如:
let counter = 5;
let interval = setInterval(() => {
$("#timerDisplay").text = counter;
counter--;
if (counter == 0) {
clearInterval(interval);
$(".detail-card").removeClass("hidden");
}
}, 1000);
您需要的是setInterval,而不是setTimeout-一旦setTimeout()
是异步的,就会触发timeout,它只告诉浏览器尽快执行传递的函数,但不能在x毫秒过去之前。但是您的浏览器正忙于运行while
循环,因此他没有时间执行该函数。它不会被调用,因为您的while(downSeconds>0)
从不让它被调用。。。成千上万的超时将被“启动”,这将永远不会触发,然后你的内存将耗尽,或者你的浏览器会告诉你一个脚本正在使系统无响应-有趣的是,你从来没有提到过that@WaldemarIce我知道,这就是为什么我有一个,而循环。我使用了setTimeout
,这样我就有了一个简单的1秒计时器来减少倒计时秒数。它们将同时运行一秒钟。您必须使用setInterval并使用clearInterval停止它。承诺的作用是什么?@profk承诺将在ms后解决。因此,当我们执行等待时间(1000)时代码>它创建了一个等待的承诺,因此代码将在一秒钟内继续。downvoter可能被一个多年的VB.NET卡住了,无法理解异步的东西。我看到所有的答案都被否决了,而且都是正确的。