Кнопка обновления не обновляется jQuery

#javascript #jquery

Вопрос:

В следующем jQuery вызовы Ajax выполняются при setinterval для обновления значений экрана, и по истечении времени ожидания интервал очищается и обновления прекращаются. Эта часть работает. Однако при нажатии пользователем кнопки «Обновить» необходимо выполнить определенное количество обновлений Ajax (10). В начале спиннер настраивается на вращение путем добавления класса, и после всех обновлений класс спиннера удаляется, чтобы остановить спиннер. Однако счетчик даже не запускается — все остальные обновления экрана работают по желанию. Что я делаю не так?

 jQuery(document).ready(function($) {
      // set an interval. The callback gets executed every interval
      var setInterval1_ID = setInterval(triggerAjax, 10000); // 10 sec updates
      var timeout1_ID = setTimeout(stopSetInterval1, 100000); // this is 100 seconds for 10 updates

      $(document).on("click", "#refresh-button", function() {
        $("#refresh-button").addClass("fa-spin");
        var count = 0;
        while (count <= 9) {
          count = count   1;
          triggerAjax();
        }
        $("#refresh-button").removeClass("fa-spin");
      });

      function stopSetInterval1() {
        // clear the interval trigger explicitly
        clearInterval(setInterval1_ID);

        // stop spinning of update wheel
        $("#refresh-button").removeClass("fa-spin");
        // also clear the timeout
        clearTimeout(timeout1_ID);
      }

      function triggerAjax() {
        $.post(my_ajax_obj.ajax_url, { //POST request
            _ajax_nonce: my_ajax_obj.nonce, //nonce extracted and sent
            action: "get_studer_readings" // hook added for action wp_ajax_get_studer_readings in php file
          },
          function(data) { // data is JSON data sent back by server in response, wp_send_json($somevariable)
            // update the page with new readings. Lets just log the value sto see if we are getting good data
            // console.log('data: ', data);
            // console.log('battery html', $('#power-battery').html());

            //Change Inverter output power value using Ajax delivered object data
            $('#power-load').html(data.pout_inverter_ac_kw   ' kW');

            // change the arrow class for Inverter Pout to Home using Ajax update
            $('#power-arrow-load').removeClass().addClass(data.inverter_pout_arrow_class);

            // Solar Power related values Ajax update
            //Change Solar output power value using Ajax delivered object data
            $('#power-solar').html(Math.round(data.psolar_kw, 2)   ' kW<br>'   '<font color="#D0D0D0">'  
              data.solar_pv_adc   'A');
            // todo need to add the SOlar-PB current at battery interface
            // update the arrow based on ajax
            $('#power-arrow-solar').removeClass().addClass(data.solar_arrow_class);

            // Change the Battery values based on Ajax update
            $('#power-arrow-battery').removeClass().addClass(data.battery_charge_arrow_class);
            //Change Inverter output power value using Ajax delivered object data
            $('#power-battery').html(data.pbattery_kw   ' kW<br>'   '<font color="#D0D0D0">'  
              data.battery_voltage_vdc   'V<br>'  
              data.battery_charge_adc   'A');

            //Change Grid AC in power and arrow calss based on Ajax updates
            //Change Inverter output power value using Ajax delivered object data
            $('#ppower-grid-genset').html(data.grid_pin_ac_kw   ' kW<br>'   '<font color="#D0D0D0">'  
              data.grid_input_vac   'V<br>'  
              data.grid_input_aac   'A');
            // change the arrow class for Inverter Pout to Home using Ajax update
            $('#power-arrow-grid-genset').removeClass().addClass(data.grid_input_arrow_class);
          });
      }
});
 

Комментарии:

1. Какой смысл вызывать функцию Ajax 10 раз подряд одним нажатием кнопки? Вы звоните triggerAjax(); по while циклу 10 раз, и нет ничего, что ждало бы возврата любого из этих запросов. Интервала нет. Все 10 запросов отправляются в один и тот же момент, и вы, вероятно, достигаете предела одновременных запросов XHR вашего браузера, делая это.

2. …но даже если бы эта часть работала, почему 10 обновлений подряд, а затем останавливаются? С точки зрения семантики пользовательского интерфейса, не имеет ли смысла иметь «один щелчок кнопки = одно обновление» или «кнопка действует как непрерывный запуск/остановка автоматического обновления» ? Поведение «всего 10 обновлений» кажется ужасно произвольным.

3. Чтобы уточнить, цель состоит в том, чтобы не обновлять непрерывно, а пакетами в зависимости от спроса. Значения меняются асинхронно. Ajax выполняет вызовы API на стороне сервера, чтобы получить асинхронные значения для обновления экрана. Я попробовал setInterval и тайм-аут, чтобы запустить его, но он сработал только в 1-й раз и не работал по требованию. Число 10 является произвольным, но оно отражает изменение значений, полученных с помощью Ajax.

Ответ №1:

$.post является асинхронным, поэтому он добавит или удалит класс в течение миллисекунды, вы можете сделать его синхронным, но это не рекомендуется, потому что это приведет к тому, что ваш браузер зависнет/не ответит, введет $("#refresh-button").removeClass("fa-spin"); обратный вызов после

 var count = 0; // <== make the variable global
jQuery(document).ready(function($) {
      .......
      // update the following
      $(document).on("click", "#refresh-button", function() {
        $("#refresh-button").addClass("fa-spin");
        count = 0;
        var thisCount = 0
        while (thisCount <= 9) {
          thisCount  ;
          triggerAjax();
        }
      });

      function triggerAjax() {
        $.post(my_ajax_obj.ajax_url, { //POST request
          .......
          function(data) {
            ...........
            $('#power-arrow-grid-genset').removeClass().addClass(data.grid_input_arrow_class);
            // add this block
            count  ; // <== update count
            if(count == 9){
                $("#refresh-button").removeClass("fa-spin"); // <== remove it here
            }
            // end block
          });
      }
});
 

приведенный выше код заставит вас запускать пост параллельно для сериализации

  $(document).on("click", "#refresh-button", function() {
    $("#refresh-button").addClass("fa-spin");
    count = 0;
    triggerAjax();
  });

function triggerAjax() {
$.post(my_ajax_obj.ajax_url, { //POST request
  .......
  function(data) {
    ...........
    $('#power-arrow-grid-genset').removeClass().addClass(data.grid_input_arrow_class);
    // add this block
    count  ;
    if(count == 9){
        $("#refresh-button").removeClass("fa-spin");
    }
    else{
        triggerAjax();
    }
    // end block
  });
}
 

Комментарии:

1. Это сделало свое дело 🙂 Я могу точно настроить задержки и количество в соответствии с требуемой скоростью отображения асинхронных данных из вызовов API в Ajax. Спасибо за помощь.