показывать данные с задержкой из jquery в каждом цикле
-
22-09-2019 - |
Вопрос
Мой вопрос заключается в следующем:
Какой наилучший способ для зацикливания некоторого массива json также показывает некоторые данные с например, с задержкой в одну секунду.
Приведенный ниже не работает, потому что он показывает только одно сообщение один раз вместо 4
jQuery.each(data.user, function(index, itemData) {
timerid = setTimeout(function(){showMessage(itemData);}, 1000);
});
function showMessage(message){
$('#status_info').html(message);
clearTimeout(timerid);
}
спасибо, Ричард
Решение
Если вы хотите избежать setInterval и просто привязать вызовы к длине вашего списка, вы можете создать самоисполняющуюся функцию, которая сохраняет ваш текущий индекс вместо использования индекса из закрытия.Переменная из замыкания в конечном итоге всегда будет последним элементом в каждом вашем цикле, поскольку цикл завершится задолго до того, как будет прочитана переменная в вашей функции setTimeout.
Вы также вызываете функцию clearTimeout, которая в данном контексте не имеет для меня особого смысла.
Вдобавок ко всему, все ваши setTimeouts будут вызваны почти в одно и то же время.Это привело бы к тому, что все значения будут мигать на экране с интервалом в миллисекунды (или слишком быстро, чтобы их можно было увидеть в некоторых случаях).Цикл здесь не совсем уместен, потому что функция setTimeout является асинхронной.Система обратных вызовов лучше всего подходит для конечного числа запусков, а система setInterval лучше всего подходит для неизвестного количества запусков.Для меня ваше количество запусков должно быть количеством элементов в вашем объекте jQuery (тех, которые в данный момент проходят через ваш $.each())
Я бы посоветовал вам сделать что-то вроде следующего обобщенного примера вашего вопроса (обобщенного, поскольку у меня нет доступа к вашему dom).
function showMessage(message){
$('body').html(message);
}
var itemData = [1,2,3,4];
var i = 0;
function idTimer(list, i) {
if (!(i >= 0)) {
i= 0;
}
setTimeout((function(msg){
i++;
return function(){
if(i < list.length){
idTimer(list, i);
}
showMessage(msg);
}
})(list[i]), 1000);
}
idTimer(itemData);
Живую демонстрацию этого кода можно найти по адресу: http://jsbin.com/ifuqo
Другие советы
Вместо этого попробуйте setInterval:
var i = 0;
window.setInterval(function() {
$('#status_info').html(data.user[i++]);
i = i == data.user.length ? 0 : i; // loops the interval
}, 1000);