简体   繁体   English

为什么我的带有 setTimeout 的倒计时功能不起作用

[英]Why my Countdown function with setTimeout doesn't work

So I developed a countdown function, in the code below I test it with a 1 minute input, but the console throws all the values at once.所以我开发了一个倒计时功能,在下面的代码中我用 1 分钟的输入测试它,但控制台一次抛出所有值。 What should happen is a number every second, I believe the problem is that setTimeout is probably not working, but how to fix?每秒应该发生一个数字,我相信问题是 setTimeout 可能不起作用,但是如何解决?

 function countdown(tempominutos) {
    let tempo = new Date();
    tempo.setHours(0, tempominutos, 0);
    let tempoformatado = tempo.toLocaleTimeString();
    console.log(tempoformatado);
    while ((tempo.getSeconds() > 0) || (tempo.getMinutes() > 0) || (tempo.getHours() > 0)) {
      tempo.setSeconds(tempo.getSeconds() - 1);
      tempoformatado = tempo.toLocaleTimeString();
      setTimeout(console.log(tempoformatado), 1000);
    }
  }
  countdown(1);

There are several problems in your code:您的代码中有几个问题:

Firstly , setTimeout 's first argument is a function, you're providing console.log(tempoformatado) which will execute console.log and evaluate to undefined .首先setTimeout的第一个参数是一个函数,您提供的console.log(tempoformatado)将执行console.log并评估为undefined

You can solve this by wrapping your statement with a function:您可以通过用函数包装您的语句来解决这个问题:

setTimeout(function() { console.log(tempoformatado) }, 1000);

Secondly , you are using the same timeout for all your callbacks.其次,您对所有回调使用相同的超时。 You need to keep in mind that your while loop is executing instantly.你需要记住你的while循环是立即执行的。 All timeouts will have finished at the exact same time and almost 1000ms after the initial tempoformatado log.所有超时将在完全相同的时间完成,并且在初始tempoformatado日志之后几乎 1000 毫秒。

To counter that you need to make the interval dependent to the time you're showing.为了解决这个问题,您需要使间隔取决于您显示的时间。 For example you could calculate 1000ms times the number of seconds:例如,您可以计算 1000 毫秒乘以秒数:

1000*tempo.getSeconds()

Finally , you need to make tempoformatado local to the while block.最后,您需要将tempoformatado设置为while块的本地。 This makes sure that each loop as its own value of tempoformatado .这确保每个循环都作为它自己的tempoformatado值。 You can do this by redefining tempoformatado with the let keyword inside the while loop您可以通过在while循环中使用let关键字重新定义tempoformatado来完成此操作

 function countdown(tempominutos) { let tempo = new Date(); tempo.setHours(0, tempominutos, 0); let tempoformatado = tempo.toLocaleTimeString(); console.log(tempoformatado); while ((tempo.getSeconds() > 0) || (tempo.getMinutes() > 0) || (tempo.getHours() > 0)) { tempo.setSeconds(tempo.getSeconds() - 1); let tempoformatado = tempo.toLocaleTimeString(); setTimeout(function() { console.log(tempoformatado) }, 1000*tempo.getSeconds()); } } countdown(1);

Your code expects setTimeout to work like a sleep function.您的代码期望 setTimeout 像睡眠函数一样工作。

Instead, replace it with the sleep function defined here: https://stackoverflow.com/a/39914235/6801443相反,将其替换为此处定义的 sleep 函数: https : //stackoverflow.com/a/39914235/6801443

 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function countdown(tempominutos) { let tempo = new Date(); tempo.setHours(0, tempominutos, 0); let tempoformatado = tempo.toLocaleTimeString(); console.log(tempoformatado); while ((tempo.getSeconds() > 0) || (tempo.getMinutes() > 0) || (tempo.getHours() > 0)) { tempo.setSeconds(tempo.getSeconds() - 1); await sleep(1000); tempoformatado = tempo.toLocaleTimeString(); console.log(tempoformatado); } } countdown(1);

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

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