Таймер js внутри цикла

507
03 сентября 2017, 04:54

Есть функция, которая отрисовывает график по полученному массиву с помощью AJAX.

// ********************************** startUpdate ******************************** //
    function startUpdate() {
        fetchData();
        data = [];
        alreadyFetched = {};
        $('#average').hide();
        var currentTemperatureHolder = $('.currentTemperatureHolder');
        function fetchData() {
            function beforeSendFunc() {
                tempSpan.hide();
                lastUpdateTimeHolder.hide();
                preloaderHolder.show();
            }
            function completeFunc(answer_code) {
                if(answer_code.responseText === 'DATA IS EMPTY') {
                    alert('Данные отсутствуют');
                    return;
                }
            }
            function showData() {
                tempSpan.show();
                lastUpdateTimeHolder.show();
                preloaderHolder.hide();
                return true;
            }
            function onDataReceived(series) {
                $('.tempSpan').text(series[+series.length - 1][1]);
                var lastUpdateTime = new Date(+series[+series.length - 1][0]  - 10800000);
                var hours = lastUpdateTime.getHours() < 10 ? '0' + lastUpdateTime.getHours() : lastUpdateTime.getHours();
                var minutes = lastUpdateTime.getMinutes() < 10 ? '0' + lastUpdateTime.getMinutes() : lastUpdateTime.getMinutes();
                var seconds = lastUpdateTime.getSeconds() < 10 ? '0' + lastUpdateTime.getSeconds() : lastUpdateTime.getSeconds();
                var lastUpdateTime = hours + ':' + minutes + ':' + seconds;
                $('.lastUpdateTime').text(lastUpdateTime);
                showData();
                data = [ series ];
                $.plot("#placeholder", data, options);
            }
            $.ajax({
                url: './getTemperature.php',
                beforeSend: beforeSendFunc,
                complete: completeFunc,
                success: onDataReceived
            });
        }
        setInterval(fetchData, 5000);
    }

Хочу в этой функции выводит время до обновления, то есть выводит в таймер 5, 4, 3, 2, 1 - пошел аякс запрос, приехал, вывел данные, и пошел 5, 4, 3...

Пробовал по-разному, но количество вызовов функции таймера растет в геометрической прогрессии. Из примера удалил функцию timer дабы не пугать общественность.

Буду благодарен корректному решению и даже подсказке.

Answer 1

Давайте вместе порассуждаем) Первое что пришло в голову, это повесить параллельно с fetchData еще один таймер, но ведь нету никакой гарантии что ответ будет прислан моментально из за этого и следует что корректный таймер мы сделать не можем. НО в вашем условии есть замечательная ремарка и в ajax запросе есть прелоадер (beforeSendFunc()). В итоге, мы делаем следующее, запускаем параллельно с основным таймером другой, который будет запускаться 1 раз в 1000 мс и который будет выполнять дикримент счетчика 5..4..3..2.. когда счетчик будет равен 0 можно ждать ответ от функции beforeSendFunc() можно с её помощью более жестко словить начало запроса, а в onDataReceived() мы снова даем счетчику значение 5

Answer 2
        // ********************************** startUpdate ******************************** //
    function startUpdate() {
        timeToRefresh.show();
        data = [];
        alreadyFetched = {};
        $('#average').hide();
        var currentTemperatureHolder = $('.currentTemperatureHolder');
        function fetchData() {
            function beforeSendFunc() {
                $('#timeToRefresh').hide();
                tempSpan.hide();
                lastUpdateTimeHolder.hide();
                preloaderHolder.show();
            }
            function showData() {
                $('#timeToRefresh').show();
                tempSpan.show();
                lastUpdateTimeHolder.show();
                preloaderHolder.hide();
            }
            function onDataReceived(series) {
                $('.tempSpan').text(series[+series.length - 1][1].toFixed(1));
                $('.tempSpan').append('&#176;C');
                var lastUpdateTime = new Date(+series[+series.length - 1][0]  - 10800000);
                var hours = lastUpdateTime.getHours() < 10 ? '0' + lastUpdateTime.getHours() : lastUpdateTime.getHours();
                var minutes = lastUpdateTime.getMinutes() < 10 ? '0' + lastUpdateTime.getMinutes() : lastUpdateTime.getMinutes();
                var seconds = lastUpdateTime.getSeconds() < 10 ? '0' + lastUpdateTime.getSeconds() : lastUpdateTime.getSeconds();
                var lastUpdateTime = hours + ':' + minutes + ':' + seconds;
                $('.lastUpdateTime').text(lastUpdateTime);
                showData();
                data = [ series ];
                $.plot("#placeholder", data, options);
            }
            $.ajax({
                url: './getTemperature.php',
                type: "post",
                beforeSend: beforeSendFunc,
                success: onDataReceived
            });
        }
        function startTimer() {
            if(icycle === 0) {
                icycle  = 61;
                fetchData();
            }
            var my_timer = $('#timeToRefresh');
            var time = my_timer.innerHTML;
            icycle --;
            icycle = icycle < 10 ? '0' + icycle : icycle;
            my_timer.text(icycle);
            icycle =+ icycle;
        }           
        setInterval(startTimer, 1000);
    }
READ ALSO
Чекбоксы и скрытые названия в заголовки

Чекбоксы и скрытые названия в заголовки

Есть 6 чекбоксовКаждый чекбокс имеет скрытые строки

471
Не могу обработать кириллицу

Не могу обработать кириллицу

Использую Nodejs для загрузки валют с центробанка

468
AngularJS querySelector не работает с ng-repeat

AngularJS querySelector не работает с ng-repeat

Помогите понять, почему этот код не работает:

513
Drag&amp;Drop и Click на одном блоке

Drag&Drop и Click на одном блоке

Подскажите пожалуйста

446