Можно ли применять 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 внутри цикла? |
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)
}
)
}
|
1. Боже, ну и говнокод...
2. Раз вы передаёте в setTimeout строку, то она должна быть в форме вызова ф-ии: setTimeout(name_function + '()', time); |
MC-XOBAHCK,
Что делают эти функции? Вы где-то свернули с правильного пути. |
Очевидно:
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 работающей с нужными данными. |
Цитата:
Спасибо - так работает. |
Я добавлю фрагмент с этими функциями, может кто ещё меня за говнокод попинает (полезно в процессе обучения).
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;'}
|
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;');
}
}
|
Я бы сделал объектом:
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,
ваш код не пишет "height: 94px;" для 34-37. Да и поддерживать простой объект проще, чем эти вложенные циклы. |
Белый шум,
Цитата:
Цитата:
|
Dilettante_Pro,
Как вы и сказали - мы не знаем закономерности в целом. А значит и не знаем - все ли значения цикличны и будет ли это правилом в будущем. В любом случае - пусть автор сам выбирает из предложенных вариантов, ему видней как лучше. |
| Часовой пояс GMT +3, время: 16:32. |