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卡住了,无法理解异步的东西。我看到所有的答案都被否决了,而且都是正确的。