#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. Спасибо за помощь.