Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Можно ли применять setTimeout внутри цикла? (https://javascript.ru/forum/misc/73596-mozhno-li-primenyat-settimeout-vnutri-cikla.html)

MC-XOBAHCK 27.04.2018 14:45

Можно ли применять setTimeout внутри цикла?
 
У меня внутри события через setTimeout вызываются функции.
Работающий пример:
document.querySelector('#shag3').addEventListener('click', function () {
    setTimeout(brus1, 400);
    setTimeout(brus2, 800);
    setTimeout(brus3, 1200);
    setTimeout(brus4, 1600);
    setTimeout(brus5, 2000);
    setTimeout(brus6, 2400);
    setTimeout(brus7, 2800);
    setTimeout(brus8, 3200);
    setTimeout(brus9, 3600);
    setTimeout(brus10, 4000);
    setTimeout(brus11, 4400);
    setTimeout(brus12, 4800);
    setTimeout(brus13, 5200);
    setTimeout(brus14, 5600);
    setTimeout(brus15, 6000);
    setTimeout(brus16, 6400);
    setTimeout(brus17, 6800);
    setTimeout(brus18, 7200);
    setTimeout(brus19, 7600);
    setTimeout(brus20, 8000);
)}


Это урезанный вариант, на самом деле у меня setTimeout в разных обработчиках событий от 50 до 400 штук.
Поэтому я пытаюсь сделать это циклом и делаю так:
document.querySelector('#shag3').addEventListener('click', function () {
   for (let i = 0; i < 50; i++) {
        let name_function = 'brus' + i;
        let time;
        
        if(i == 0) time = 10;
        else time = 400 * i;

        setTimeout(name_function, time);

        console.log(name_function + ' и ' + time);
    }
)}

но это не работает - функции из setTimeout не вызываются : (
При этом в console.log выводятся правильные значения.

Поэтому у меня вопрос: а можно ли применять setTimeout внутри цикла?

Nexus 27.04.2018 14:53

MC-XOBAHCK, попробуйте так:
document.querySelector('#shag3').addEventListener('click', function() {
        for (let i = 0; i < 50; i++) {
			(function(i){
				let name_function = 'brus' + i;
				let time;

				if (i == 0) time = 10;
				else time = 400 * i;

				setTimeout(name_function, time);

				console.log(name_function + ' и ' + time);
			})(i)
        }
    )
}

Белый шум 27.04.2018 15:28

1. Боже, ну и говнокод...

2. Раз вы передаёте в setTimeout строку, то она должна быть в форме вызова ф-ии:
setTimeout(name_function + '()', time);

j0hnik 27.04.2018 15:30

MC-XOBAHCK,
Что делают эти функции?
Вы где-то свернули с правильного пути.

Aetae 27.04.2018 15:32

Очевидно:
setTimeout(name_function + '()', time)
, или, возможно,
setTimeout(window[name_function], time)

Но на самом деле это хрень полная, потому что если браузер чуть подтормозит все эти таймауты сработают подряд да и так время срабатывания будет далеко от прогнозированного: setTimeout лишь удостоверяется, что срабатывание будет не раньше time, остальное зависит загруженности страницы.
Делать надо примерно так:
var functions = Array.from({length:20}, (e,i) => eval('brus' + (21-i));
(function next(){
  functions.pop()();
  if(functions.length) 
    setTimeout(next, 400);
}())
И то уродливо, т.к. с вероятностью 99% все эти функции brus по сути одинаковы и отличаются лишь каким то значением, а потому вообще не нужны и всё можно свести к функции next работающей с нужными данными.

MC-XOBAHCK 27.04.2018 15:40

Цитата:

Сообщение от Белый шум (Сообщение 484250)
ну и говнокод...
setTimeout(name_function + '()', time);

Да, я = говнокодер().
Спасибо - так работает.

MC-XOBAHCK 27.04.2018 15:44

Я добавлю фрагмент с этими функциями, может кто ещё меня за говнокод попинает (полезно в процессе обучения).
function brus16() {br[16].style.cssText = 'left: 763px; bottom: 0'}
function brus17() {br[17].style.cssText = 'left: 0; bottom: 100px'}
function brus18() {br[18].style.cssText = 'left: 50px; bottom: 100px'}
function brus19() {br[19].style.cssText = 'left: 100px; bottom: 100px'}
function brus20() {br[20].style.cssText = 'left: 150px; bottom: 100px'}
function brus21() {br[21].style.cssText = 'left: 200px; bottom: 100px'}
function brus22() {br[22].style.cssText = 'left: 250px; bottom: 100px'}
function brus23() {br[23].style.cssText = 'left: 300px; bottom: 100px'}
function brus24() {br[24].style.cssText = 'left: 350px; bottom: 100px'}
function brus25() {br[25].style.cssText = 'left: 400px; bottom: 100px'}
function brus26() {br[26].style.cssText = 'left: 450px; bottom: 100px'}
function brus27() {br[27].style.cssText = 'left: 500px; bottom: 100px'}
function brus28() {br[28].style.cssText = 'left: 550px; bottom: 100px'}
function brus29() {br[29].style.cssText = 'left: 600px; bottom: 100px'}
function brus30() {br[30].style.cssText = 'left: 650px; bottom: 100px'}
function brus31() {br[31].style.cssText = 'left: 700px; bottom: 100px'}
function brus32() {br[32].style.cssText = 'left: 750px; bottom: 100px'}
function brus33() {br[33].style.cssText = 'left: 763px; bottom: 100px'}
function brus34() { br[34].style.cssText = 'left: 0; bottom: 200px; height: 94px;'}
function brus35() { br[35].style.cssText = 'left: 50px; bottom: 200px; height: 94px;'}
function brus36() { br[36].style.cssText = 'left: 100px; bottom: 200px; height: 94px;'}
function brus37() { br[37].style.cssText = 'left: 150px; bottom: 200px; height: 94px;'}

Dilettante_Pro 27.04.2018 16:00

for(var i = 0; i<3;i++) {
   for(var j = 0;j<17;j++) {
       console.log('br[' + (j  + i * 17) + '] left:' + j*50 + 'px; bottom:' + i*100 + 'px;');
   }
}

Белый шум 27.04.2018 16:46

Я бы сделал объектом:
function brus(i) {
  var style = {
    16: 'left: 763px; bottom: 0',
    17: 'left: 0; bottom: 100px',
    // и т.д.
  }
  //br[i].style.cssText = style[i];
  console.log('br['+i+'].style.cssText = ' + style[i]);
}

function timer(n) {
  brus(n);
  if( n < 17 ) setTimeout('timer('+(n+1)+')', 400);
}
timer(16)

Dilettante_Pro 27.04.2018 17:12

Белый шум,
А зачем объектом, если он вычисляемый по индексам?
Главное, что мы не знаем задачу в целом - может, там все не так надо делать?


Часовой пояс GMT +3, время: 22:42.