Последовательное выполнение SetTimeout()

71
25 марта 2022, 22:50

Решился сделать анимацию с плавной сменой фона у блока. Пробовал сначала в CSS через keyframe но не получил нужный результат а именно после каждых 10 секунд сделать плавную смену фона за 0.5 секунды. Решил использовать SetTimeout()

function bgOne() {cont.removeClass(one).addClass(two)};
    function bgTwo() {cont.removeClass(two).addClass(three)};
    function bgThree() {cont.removeClass(three).addClass(four)};

    setTimeout(bgOne, 5000);
    setTimeout(bgTwo, 5000);
    setTimeout(bgThree, 5000);

где one, two, three, four - переменные содержащие CSS клас с нужным фоном; а cont - элемент DOM дерева

После 5 секунд с загрузки страницы выполнились сразу все SetTimeout()

Вопрос, как заставить их выполняться последовательно только после окончания предыдущего?

Answer 1

Ну можно просто дописать вызов следующей функции - внутри предыдущей. Цепочка вызовов:

setTimeout(bgOne, 5000);
function bgOne() {
  cont.removeClass(one).addClass(two);
  setTimeout(bgTwo, 5000);
}
function bgTwo() {
  cont.removeClass(two).addClass(three);
  setTimeout(bgThree, 5000);
}
function bgThree() {
  cont.removeClass(three).addClass(four);
  setTimeout(bgOne, 5000);
  /* Например третья может вызвать снова первую - пойдет бесконечный цикл */
}

Хотя на самом деле можно делать одну функцию, названия классов хранить в массиве и переключать классы по индексу:

let bubu = ["one", "two", "three", "four"]; 
let i = 0; 
 
let int = setInterval(function() { 
  let next = (i + 1) % bubu.length; 
  console.log("Remove: " + bubu[i], "/// add: " + bubu[i = next]); 
 
  // if( ??? ) clearInterval(int); 
}, 2000);

Answer 2

body { 
  margin: 0; 
  height: 100vh; 
  background-color: tomato; 
  animation: changeBackground 40s infinite; 
} 
 
@keyframes changeBackground { 
  0%, 20% { 
    background-color: tomato; 
  } 
   
  25%, 45% { 
    background-color: lightblue; 
  } 
   
  50%, 70% { 
    background-color: lightgreen; 
  } 
   
  75%, 95% { 
    background-color: crimson; 
  } 
}

Answer 3

function bgOne() {console.log('bgOne')}; 
function bgTwo() {console.log('bgTwo')}; 
function bgThree() {console.log('bgThree')}; 
 
 
setTimeout(() => { 
  bgOne(); 
  setTimeout(() => { 
    bgTwo(); 
    setTimeout(() => { 
      bgThree(); 
    }, 2000); 
  }, 2000); 
}, 2000);

Надо ещё через промисы подумать как сделать, чтоб с async/await можно было заюзать. А то громоздкач конструкция.

Answer 4

/** 
 * @param args - {func, timeout} 
 */ 
 
function startTimeouts(...args) { 
  let iterator = queue(args.flat(Infinity)); 
  iterator.next(); 
 
  function* queue(args) { 
    for (let currentTimeout of args) { 
      yield setTimeout(() => { 
          currentTimeout.func(); 
          iterator.next(); 
        }, currentTimeout.timeout); 
    } 
  } 
} 
 
 
startTimeouts( 
  {func() {console.log(0)}, timeout: 0}, 
  {func() {console.log(1)}, timeout: 1000}, 
  {func() {console.log(2)}, timeout: 500}, 
  {func() {console.log(3)}, timeout: 500}, 
  {func() {console.log(4)}, timeout: 1500}, 
); 
 
startTimeouts( 
  [{func() {console.log(0)}, timeout: 0}, 
  {func() {console.log(1)}, timeout: 1000}, 
  {func() {console.log(2)}, timeout: 500}, 
  {func() {console.log(3)}, timeout: 500}, 
  {func() {console.log(4)}, timeout: 1500}] 
);

READ ALSO
Генераця ELF файлов

Генераця ELF файлов

K примеру у меня есть байтовый массив готовых опкодовКак мне сгенерировать ELF файл вместе с этими опкодами? Есть ли какая-то готовая библиотека...

107
Ханойская башня с массивами C++

Ханойская башня с массивами C++

Можете объяснить мне как реализовать это с массивами, представьте эти стержни и кольца так:

110
c++ переопределение оператора + с использованием конструкции {x, y}

c++ переопределение оператора + с использованием конструкции {x, y}

Подскажите, можно ли реализовать следующую вещь:

99
Выдвигающееся меню PyQt

Выдвигающееся меню PyQt

Возможно ли реализовать выдвигающееся меню нa Pyqt5 ?!

98