0

I'm trying to create a counter, that updates every 1 second. I've made a backend function that returns every 30 seconds, which is called with Ajax. The result from the call is divided by 30 and should then update the counter every 1 second for 30 seconds. How would I go about putting a sleep in the for-loop?

This is my code so far:

function getCount() {
    $.ajax({
        url: '@Url.Action("", "", new {area = ""})',
        type: 'POST',
        success: function (data) {
            var newTotalCount = data.totalCount;
            var newDanishCount = data.danishCount;
            var newNorwayCount = data.norwayCount;
            var newSwedenCount = data.swedenCount;
            var newUsCount = data.usCount;

            var currentTotalCount = $("#odoTotal").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
            var currentDanishCount = $("#odoDk").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
            var currentNorwayCount = $("#odoNo").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
            var currentSwedenCount = $("#odoSe").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
            var currentUsCount = $("#odoUs").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");

            var updateTotalCount = newTotalCount - currentTotalCount;
            var updateDanishCount = newDanishCount - currentDanishCount;
            var updateNorwayCount = newNorwayCount - currentNorwayCount;
            var updateSwedenCount = newSwedenCount - currentSwedenCount;
            var updateUsCount = newUsCount - currentUsCount;

            var updateTotalPerSecond = updateTotalCount / 30;
            var updateDanishPerSecond = updateDanishCount / 30;
            var updateNorwayPerSecond = updateNorwayCount / 30;
            var updateSwedenPerSecond = updateSwedenCount / 30;
            var updateUsPerSecond = updateUsCount / 30;


            getAllSales();

            for (var i = 0; i < 30; i++) {
                window.setTimeout(function() {
                    $("#odoTotal").html(currentTotalCount+updateTotalPerSecond);

                    $("#odoDk").html(currentDanishCount+updateDanishPerSecond);

                    $("#odoNo").html(currentNorwayCount+updateNorwayPerSecond);

                    $("#odoSe").html(currentSwedenCount+updateSwedenPerSecond);

                    $("#odoUs").html(currentUsCount+updateUsPerSecond);

                    currentTotalCount = $("#odoTotal").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
                    currentDanishCount = $("#odoDk").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
                    currentNorwayCount = $("#odoNo").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
                    currentSwedenCount = $("#odoSe").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");
                    currentUsCount = $("#odoUs").text().replace(/,/g, "").replace(/(\r\n|\n|\r)/gm, "");


                }, 1000);

            }

        }
    });

}
Jannik
  • 391
  • 1
  • 3
  • 15
  • I'd look at RxJS, it's a great tool for handling async cases like these. It might be an overkill, though. – Klaster_1 Dec 23 '16 at 08:27
  • 1
    Possible duplicate of [How do I add a delay in a JavaScript loop?](http://stackoverflow.com/questions/3583724/how-do-i-add-a-delay-in-a-javascript-loop) – Rajesh Dec 23 '16 at 08:28
  • simple but ultimately stupid solution - change timeout from `1000` to `(i + 1) * 1000` – Jaromanda X Dec 23 '16 at 08:32

2 Answers2

2

I got a solution for that

First create a variable which you will going to increment

var x = 0;

then create an interval which will do what you wanted after an a time ended for example 5(s), This will also increment your value x every time it run

var interval = setInterval(function() {
    if (x >= 5) { // just change 5 to 30
        console.log('Loop timeout ended');
        return clearInterval(interval);
    }
    // do what ever you want
    console.log('Current x: '+x);
    x++;
}, 5000); 

example function

function runTimeoutLoop(){
    var x = 0;
    var interval = setInterval(function() {
        if (x >= 5) { // just change 5 to 30
            console.log('Loop timeout ended');
            return clearInterval(interval);
        }
        // do what ever you want
        console.log('Current x: '+x);
        x++;
    }, 5000); 

}

Demo

Beginner
  • 3,960
  • 3
  • 16
  • 26
  • I feel like this is a great approach, although I find that the JSFiddle you attached only counts once. :-( – Jannik Dec 23 '16 at 09:47
  • @Jannik what do you mean once?I tried it and it wait 5(s) for every index which what you wanted. – Beginner Dec 23 '16 at 09:55
  • I just tried in Chrome and that works - for some reason I cannot get it to work in Firefox. – Jannik Dec 23 '16 at 10:57
  • Ok but means u wont accept my answer? Ok I fix it on firefox wait – Beginner Dec 23 '16 at 11:35
  • @Jannik actually it's working in firefox it's just that firefox wont allowed the next document.write check this using console(f12) https://jsfiddle.net/f8zm5os9/1/ – Beginner Dec 23 '16 at 12:09
0

If you use Firefox 53+, or babel you can use ES2017:

async function promiseTimeout(milliseconds) {
    await new Promise(resolve => setTimeout(()=>resolve(), milliseconds))
}

async function countDown(from) {
    while (from) {
        console.log(from--, 'seconds left');
        await promiseTimeout(1000);
    }
    alert('countdown done');
}

countDown(10);

Here it is with babel.

Farshid Shekari
  • 1,941
  • 4
  • 23
  • 45
Noitidart
  • 32,739
  • 29
  • 126
  • 286