如何防止setInterval同时被多次调用?

How to prevent setInterval from being called multiple times simultaneously?

有没有办法让 setInterval 一次只工作一次? 我的代码应该这样工作:

  1. 您手动输入秒数;
  2. “div”作为计时器运行,直到达到 0。

如果您单击“单击我”一次,它将按预期工作。 但是,如果您足够快地多次单击该按钮,则偶数侦听器将同时工作与您单击的次数一样多。

let button = document.getElementById('button');
let input = document.getElementById('input');
let timer = document.getElementById('timer');

function timerRunner () {
    let startTime = input.value;
    if (startTime <= 0) {
        console.log('The number is <=0')
    } else {
        do {
            timer.textContent = startTime;
            let counter = startTime;
            let interval = setInterval(()=> {
                console.log(counter);
                counter--;
                timer.textContent = counter;
                if (counter === 0) {
                    clearInterval(interval);
                }
            }, 1000);
        } while (typeof (timer.textContent) == "number");
    }
}

button.addEventListener('click', timerRunner)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .centeralizer {
            display: block;
            width: 200px;
            margin: 20vh auto;
        }
        #input {
            display: block;
            margin-bottom: 35px;
            width: 150px;
        }
        #button {
            display: inline-block;
            margin-right: 35%;
        }
        #timer {
            display: inline-block;
        }
    </style>
    <script src="index.js" defer></script>
</head>
<body>
<div class="centeralizer">
    <input id="input" placeholder="Input the number" type="number">
    <button id="button">Click me</button>
    <div id="timer">0</div>
</div>
</body>
</html>

您可以添加一个布尔变量 isRunning 来跟踪计时器是否 运行。当计时器为 运行 时将其设置为开启,并在计时器结束时将其关闭。单击按钮时检查它是否打开,如果是 return。您可以防止触发多个计时器实例。

let button = document.getElementById('button');
let input = document.getElementById('input');
let timer = document.getElementById('timer');

var isRunning = false;

function timerRunner () {
    if(isRunning) {
         return; //return if timer is already running
    }
    isRunning = true; //specify that the timer is running

    let startTime = input.value;
    if (startTime <= 0) {
        console.log('The number is <=0')
    } else {
        do {
            timer.textContent = startTime;
            let counter = startTime;
            let interval = setInterval(()=> {
                console.log(counter);
                counter--;
                timer.textContent = counter;
                if (counter === 0) {
                    isRunning = false; //specify that the timer is not running and can be run again
                    clearInterval(interval);
                }
            }, 1000);
        } while (typeof (timer.textContent) == "number");
    }
}

button.addEventListener('click', timerRunner)

你应该将运行间隔存储在上层范围内,如果再次按下按钮则清除它。

const button = document.getElementById('button');
const input = document.getElementById('input');
const timer = document.getElementById('timer');

let interval = null;

function startTimer() {
    const startTime = +input.value;

    if (startTime <= 0) {
        console.log('The number is <= 0');
        return;
    }
    
    let counter = startTime;
    timer.textContent = startTime;
    if (interval) clearInterval(interval);
    
    interval = setInterval(() => {
        timer.textContent = --counter;
        console.log(counter);
        if (counter === 0) clearInterval(interval);
    }, 1000);
}

button.addEventListener('click', startTimer)