JSFiddle - React, Tailwind, and code Playground

JavaScript

function CountdownTimer(totalMs, totalTicks, tickCb) {

    var ret = {}, startTime, ticksCompleted;

    function tick() {
        ticksCompleted++;
        tickCb(ticksCompleted);
        if (ticksCompleted == totalTicks) {
            onFinish();
        } else {
            var pause = optimalPauseTime();
            if (pause <= 0) tick();
            else setTimeout(tick, pause);
        }
    }

    function optimalPauseTime() {
        var timeElapsed = new Date() - startTime;
        var nextTickRatio = (ticksCompleted + 1) / totalTicks;
        var expectedNextTime = totalMs * nextTickRatio;
        //console.log(timeElapsed, nextTickRatio, expectedNextTime); 
        return expectedNextTime - timeElapsed;
    }

    function start() {
        startTime = new Date();
        ticksCompleted = 0;
        tick();
    }

    function onFinish() {
        console.log(new Date() - startTime);
    }

    ret.start = start;
    return ret;
}

timer = CountdownTimer(5000, 2000, function (tickNum) {
    console.log(tickNum)
});
timer.start();