如何两次无限重复javascript setInterval计时器

时间:2015-11-08 02:23:15

标签: javascript jquery loops timer setinterval

我正在研究一个运行一定时间的计时器,然后重新开始一段时间倒计时,然后再回到原来的分钟数。我正在努力克服逻辑。到目前为止,我让它在原始时间运行,然后运行中断计时器,但我需要帮助使它返回到原始时间并无限循环(或直到按下停止按钮)。这就是我所拥有的:

    function timer(minutes, breakLength) {

    --minutes;

    timerId = setInterval(function() {

        if (minutes >= 0) {

            if (seconds > 0) {
                --seconds;
            }

            if (seconds == 0 && minutes == 0) {
                playSound();
                isBreak = true;
                minutes = breakLength;
                $('.type').html('Break');
                $('.timer').html(minutes + ':00');

            };

            if (seconds === 0) {
                seconds = 59;
                --minutes;
            }

            if (seconds < 10) {
                seconds = '0' + seconds;
            }

            $('.timer').html(minutes + ':' + seconds);
        }
    }, 1000);

}

我怎样才能重复这个?

2 个答案:

答案 0 :(得分:3)

在计时器功能范围内将新变量定义为超时ID持有者(让我们称之为resetTimeout):

var resetTimeout = null;

将此附加代码添加到主函数

var runFor = 60000; // 60000ms or 1 minute

在主间隔(第一行)中添加逻辑:

if(runFor <= 0) {
    if(!resetTimeout) {
       // Create a reset timeout
       resetTimeout = setTimeout(function(){ runFor = 60000; resetTimeout = null; }, breakLength);
    }
    return;
}
else {
    runFor -= 1000; // Deduct time of this interval
}

此逻辑从runFor中扣除1000毫秒或1秒,直至完全耗尽。然后创建一个timeOut函数,将其重置为原始值并返回当前函数,直到runFor更新为止。我使用60000毫秒作为示例,您可以在下面的完整代码中看到正确的版本。为什么我们将超时分配给变量?这很简单,我们不想创建多个超时。我们将超时设置为null以允许在下一个时间间隔进行重新创建。

请注意,有更好的方法可以做到这一点,但我决定对代码进行尽可能少的修改。

以下是工作代码:

function timer(minutes, breakLength) {
    var seconds = 0;
    var originalMinutes = minutes;
    var resetTimeout = null;
    var totalRunFor = minutes * 60 * 1000; // Since minutes are independent
    var runFor = totalRunFor;

    timerId = setInterval(function() {
        if(runFor <= 0) {
            if(!resetTimeout) {
                
                // Create a reset timeout
                resetTimeout = setTimeout(function(){ runFor = totalRunFor; resetTimeout = null; }, breakLength);
            }
            return;
        }
        else {
            runFor -= 1000; // Deduct time of this interval
        }

        if (minutes >= 0) {

            if (seconds > 0) {
                --seconds;
            }

            if (seconds == 0 && minutes == 0) {
                //playSound();
                isBreak = true;
                minutes = originalMinutes;
                $('.type').html('Break');
                $('.timer').html(minutes + ':00');

            };

            if (seconds === 0) {
                seconds = 59;
                --minutes;
            }

            $('.timer').html(minutes + ':' + ((seconds < 10)?'0':'') + seconds);
        }
    }, 1000);

}
timer(1, 10000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Run for a minute and stop for 10 seconds indefinitely.
<div class='type'></div>
<div class='timer'></div>

答案 1 :(得分:1)

从概念上讲,在timer函数

中将其分成多个函数可能更容易
function timer(minutes, breakLength) {
    var ci = null;

    function ACountdown(minutes, callback) {
        var mm = minutes,
            ss = 0;
        ci = setInterval(function () {
            --ss;
            if (ss < 0)
                ss += 60, --mm;
            if (mm < 0) {
                // done
                clearInterval(ci);
                setTimeout(callback, 0);
            } else {
                $('.timer').html(mm + ':' + seconds);
            }
        }, 1e3);
    }

    function A() {
        // returned from break
        $('.type').html = 'Countdown';
        ACountdown(minutes, B);
    }
    function B() {
        // just finished countdown
        playSound();
        // going on break
        $('.type').html = 'Break';
        ACountdown(breakLength, A);
    }

    // set up any click handlers here, e.g.
    document.getElementById('cancel_button').addEventListener('click', function c() {
        this.removeEventListener('click', c);
        clearInterval(ci);
    });

    // start invocation chain
    A();
}