Помогите с задержкой(setinterval) условий


#1

Вкратце, опишу проблему - возникла проблема с пониманием таких команд, как setinterval и settimeout.
Цель была сделать на условиях сделать задержку в 3 секунды, когда эти же условия ходят по циклу(for)… Фактически пример это и есть данный код, именно сейчас все работает, как предполагается, только данный способ меня не устраивает, ибо каждый раз цикл умножая на себя, увеличивает скорость задержки, хотелось бы уйти от данного ускорения.
Очень долго пытался уяснить куда поставить и что сделать, в итоге результат 0, решил обратится к более опытным людям, которые встречались с данной командой.
P.S. Заранее спасибо, прошу разъяснить данную команду и её особенность работы и прошу прощения, что нету комментариев, на данный момент добавить их не предоставляется возможным мне…

JS
var image = new Array(4);

image[0] = { 'small': "small-0", 'big': "big-0" };
image[1] = { 'small': "small-1", 'big': "big-1" };
image[2] = { 'small': "small-2", 'big': "big-2" };
image[3] = { 'small': "small-3", 'big': "big-3" };
image[4] = { 'small': "small-4", 'big': "big-4" };

var active_image = 0;
var last_image = 0;

for (var i = 1; i < 100; i++) {
    setTimeout(function() {

        if (last_image == 0) {

            $("#slide-0").html(image[0].small);
            $("#slide-1").html(image[1].small);
            $("#slide-2").html(image[2].small);
            $("#slide-3").html(image[3].small);
            $("#slide-4").html(image[4].big);

            last_image = 4;
        } else {

            if (last_image == 4) {
                $("#slide-1").html(image[last_image].small);
                $("#slide-4").html(image[1].big);
                last_image = 1;
            }

            if (last_image < 4) {
                active_image = last_image + 1
                $("#slide-" + active_image).html(image[last_image].small);
                $("#slide-4").html(image[active_image].big);

                if (active_image < 4) {
                    last_image = active_image;
                } else {
                    $("#slide-0").html(image[0].small);
                    $("#slide-1").html(image[1].small);
                    $("#slide-2").html(image[2].small);
                    $("#slide-3").html(image[3].small);
                    $("#slide-4").html(image[4].big);

                    last_image = 4;
                }
            }
        }
        console.log(i);
    }, 3000 * i);
}

HTML

 <div id="slide-0">0</div> 
 <div id="slide-1">1</div> 
 <div id="slide-2">2</div> 
 <div id="slide-3">3</div> 
 <div id="slide-4">4</div> 
</body>

#2

здесь идет ускорение, потому что i меняется на каждой итерации цикла. Чтобы не было ускорения должно быть одно значение, а не разное на каждой итерации.


#3

Оно и понятно… Но если я ставлю обычную переменную, она потом не дает такого эффекта, как i.


#4

Не понятно какой вам нужен эффект. Чтобы было 3 секунды нужно

}, 3000);

#5

Эффект, как при условии i, если посмотреть на результат - каждые 3 секунды меняется расстановка массива.
Опять же проблема в том, что каждые цикл - задержка уменьшается за счет увеличение i и хотелось бы, избежать увеличение скорости, но чтобы осталась все, как иначе - каждые 3 секунды меняется расстановка массива.
Если же i поменять на другую переменную, почему-то задержка становится вечной… Как я понял он доходит до }, 3000); и дальше цикл не идет…


#6

нужно 3000 чтобы было 3 секунды.


#7

https://jsfiddle.net/KsOD/L86vgtqh/1/

Если же убрать переменную i и просто оставить 3 секунды, то ломается задержка, она проходит один раз и все, потом цикл просто 100 раз проходит. Когда мне надо, чтобы каждый цикл по каждой if шла задержка в 3 секунды…


#8

Потому что так, как у тебя не делается. Нужно либо через setInterval() либо еще лучше через рекурсивный setTimeout()


#9

Как работает setInterval и setTimeout.

Лучше почитать документацию. Более точно чем она никто не расскажет. Я могу рассказать только упрощенную модель их работы.

setInterval это способ сказать “вот эта функция будет выполняться примерно каждые N миллисекунд”.
setTimeout - “эта функция выполнится примерно через N миллисекунд”.

Я пишу “примерно” не спроста. Конкретные значения через сколько выполнятс функции не гарантируются. Только гарантируются что оно будет очень близко к указанному значению таймаута или интервала. Это значит что нельзя завязывать логику на конкретные значения таймаутов и интервалом (ты этого и не делаешь).

каждые 3 секунды меняется расстановка массива.

Я так понял ты хочешь добиться этого эффекта.

Сейчас код работает так как хотелось потому что создается куча таймаутов в цикле и они выполняются один за другим.

Судя по коду ты делаешь что-то вроде галереи. Тут строить стратегию иначе: “Я запущу интервал, и каждые N миллисекунд он будет проверять состояние галереи и изменять его если необходимо”.

Псевдокод такой:


var currentActive = 0
var max = 4

function setActive(index) {
	// по индексу элемент который должен быть понять как поменять DOM чтобы это отобразить
}

function setNextActive() {
	if (currentActive === max) {
		currentActive = 0
	} else {
		currentActive += 1
	}
	setActive(currentActive)
}

setInterval(function () {
	setNextActive()
}, 3000)

Еще я писал подобное решение если посмотришь на структуру, можешь лучше понять что делать в твоем случае: https://www.dropbox.com/s/8pk1m90bxsd9zph/slider.zip?dl=0. Там функционала больше чем в твоем примере. Но вести он будет как в твоем примере если ничего не кликать. Точка входа в логику перелистывания: Slider.prototype.start