JavaScript | Как остановить setInterval() через 10 вызовов функции обратного вызова?

JavaScript | Как остановить setInterval() через 10 вызовов функции обратного вызова?

В JavaScript кусочки кода оборачиваются в функции, когда нужно сохранить именованное представление определённой логики работы участка из всей программы.

В нашем случае нам нужно создать некоторый счётчик, который будет виден функцией setInterval() и функцией обратного вызова. Этот счётчик будет сам являться функцией.

Итого получаем 3 функции.

 

Решение задачи

Давайте сперва создадим главную функцию, которая будет хранить всю логику работы:

function call10times (){}

Теперь у нас есть контейнер для ограниченного запуска интервального таймера. Мы назвали его call10times(). В этом контейнере будут замкнуты нужные нам переменные и функции.

 

Теперь создадим переменную step, которая будет хранить шаг текущего вызова интервального таймера. Ещё мы объявляем переменную id, которая будет хранить в себе идентификатор из «Карты Активных Таймеров» браузера в момент первого и единственного вызова «интервала».

function call10times (){
  let step = 0;
  let id = 0;
  function stepplus(){(step < 10)?console.log(step+=1):clearInterval(id)}
  return id = setInterval(stepplus, 500)
}

Внутри мы объявляем функцию stepplus(), которая будет увеличивать значение шага на единицу, когда его значение меньше 10. И возвращать она будет очистку интервала, когда значение шага станет 10 и более. Её тело мы оформили тернарным оператором (УСЛОВИЕ?ДЕЙСТВИЕ ЕСЛИ ВЕРНО:ДЕЙСТВИЕ ЕСЛИ ЛОЖНО).

В таком виде функция мало полезна т. к. она просто выводит в консоль значения текущего шага вызова интервала. Давайте её сделаем более универсальной.

Пример работы:

10 раз вызвали коллбэк console.log в таймере setInterval() и остановили его - JavaScript
10 раз вызвали коллбэк console.log в таймере setInterval() и остановили его — JavaScript

 

Улучшение № 1 — Передача нужной нам функции обратного вызова в качестве параметра в call10times()

Представим, что у нас уже есть какая-то функция с логикой работы, которую мы хотим вызывать в интервале ограниченное количество раз. Давайте её передадим.

function call10t (myfun){
  let step = 0;
  let id = 0;
  function stepplus(){
    if (step < 10) { return step+=1, myfun() } 
    else { return clearInterval(id)}
  }
  return id = setInterval(stepplus, 500)
}

Пример вызова с передачей стрелочной функции в качестве параметра:

call10t (()=>console.log(1))

Пример работы:

Передали функцию под коллбэк интервала - 10 раз вызвали коллбэк в таймере setInterval() и остановили его - JavaScript
Передали функцию под коллбэк интервала — 10 раз вызвали коллбэк в таймере setInterval() и остановили его — JavaScript

 

Улучшение № 2 — передача с аргументами

Если мы хотим передавать коллбэк с параметрами, то мы можем учитывать передачу этих параметров двумя способами. Всё что будет добавлено через запятую после слова  myfun, будет попадать в объект arguments.

function call10ti (myfun){
  let step = 0;
  let id = 0;
  let a = arguments;
  function stepplus(){
    if (step < 10) { return step+=1, myfun(...[...a].slice(1)) } 
    else { return clearInterval(id)}
  }
  return id = setInterval(stepplus, 500)
}

Пример для вызова:

call10ti (console.log, 1)
call10ti (console.log, 777, 555)

Пример работы:

Передали коллбек и несколько параметров для проброса в setInterval() через объект arguments - JavaScript
Передали коллбек и несколько параметров для проброса в setInterval() через объект arguments — JavaScript

 

Можно воспользоваться встроенной в JavaScript конструкцией через оператор spread — троеточие.

function call10tim (myfun, ...args){
  let step = 0;
  let id = 0;
  function stepplus(){
    if (step < 10) { return step+=1, myfun(...args) } 
    else { return clearInterval(id)}
  }
  return id = setInterval(stepplus, 500)
}

Пример для вызова:

call10ti (console.log, 22)
call10ti (console.log, 44, 999)

Пример работы:

Передали коллбек и несколько параметров для проброса в setInterval() через spread - JavaScript
Передали коллбек и несколько параметров для проброса в setInterval() через spread — JavaScript

 

Улучшение № 3 — дополнительная передача требуемого количества вызовов интервального коллбека

Можно воспользоваться встроенной в JavaScript конструкцией через оператор spread — троеточие.

function callanytimes (myfun, times, ...args){
  let step = 0;
  let id = 0;
  function stepplus(){
    if (step < times) { return step+=1, myfun(...args) } 
    else { return clearInterval(id)}
  }
  return id = setInterval(stepplus, 100)
}

Пример для вызова:

callanytimes (console.log, 3, 'TikTak')
callanytimes (console.log, 12, 'TikTak')
callanytimes (console.log, 12, 'TikTak', 'BomBom')

Пример работы:

Несколько раз вызвали коллбэк console.log в таймере setInterval() и остановили его. Количество вызовов передали - JavaScript
Несколько раз вызвали коллбэк console.log в таймере setInterval() и остановили его. Количество вызовов передали — JavaScript

 

 

Информационные ссылки

JavaScript | Как остановить setInterval()?

HTML | Таймеры

Стандарт ECMAScript — Раздел «14.3.3 Destructuring Binding Patterns» — https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-destructuring-binding-patterns

Стандарт HTML — Раздел «Timers» — https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers