JavaScript | Как создать временную паузу внутри тела функции?

JavaScript | Как создать временную паузу внутри тела функции?

Как приостановить выполнение алгоритма функции на некоторое время?

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

Одной из реализаций «ждущей функции» в JavaScript является использование ключевого слова «async» перед ключевым словом «function«. В нашем примере эта функция будет называться f1(). Такая функция помечается в среде выполнения кода как «асинхронная».

// Функция паузы
function pause(seconds=5000){
  return new Promise((resolve, reject) => {
    setTimeout(resolve, seconds)
  })
}

// Функция с паузой
async function f1(){
  console.log(`Вызвали f1()`, new Date().toLocaleString())
  await pause()
  console.log(`Подождали паузу`, new Date().toLocaleString())
  await pause()
  console.log(`Подождали паузу`, new Date().toLocaleString())
  console.log(`Функция f1() завершила работу!`, new Date().toLocaleString())
}

// Вызываем функцию с паузой
f1()

Но для полноценного рабочего механизма задержек в алгоритме, нам нужно создать вспомогательную функцию, которая будет возвращать нам объект Обещания.

В таком случае мы сможем работать с асинхронностью и таймерами среды выполнения кода. Сам объект Обещания будет разрешаться в тот момент, когда таймер отсчитает 5 секунд. Наше Обещание всегда выполняется по истечении этого времени (или времени, которое передаст пользователь в функцию pause()). Наше Обещание никогда не отклоняется, поэтому не нужно перехватывать отклонения.

Чтобы сказать нашей «асинхронной» функции о местах «остановки/паузы» в этом месте мы должны написать ключевое слово «await» перед Обещанием или перед функцией, которая возвращает Обещание, или перед другой Асинхронной функцией (такой у нас нет).

Выражение «await pause()» говорит нам о том, что сначала функция вернёт нам объект Обещания, а ключевое слово «await» попытается вытащить результат у этого Обещания, когда оно разрешится. В таком виде нас не интересует результат Обещания и мы его никуда не сохраняем. Мы только используем механизм задержки. В результате мы получаем эффект «паузы/задержки», который сами искусственно реализовали.

 

Зачем нужно делать временную паузу в действиях алгоритма функции?

Любой стандартный алгоритм в JavaScript старается как можно быстрее выполнить поставленную задачу. Чем больше данных вращается в оперативной памяти и чем меньше данных получаем с диска, тем быстрее будет выполняться алгоритм. Это нормально. Так и должно быть.

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

 

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

Стандарт ECMAScript — Раздел «27.2 Promise Objects» — https://tc39.es/ecma262/#sec-promise-objects

Стандарт HTML (whatwg) — Таймеры — https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers

JavaScript | setTimeout()