Функция js setTimout и sleep в JavaScript

JavaScript
61831
Функция js setTimout и sleep в JavaScript
Active vision

Во многих языках программирования есть функция sleep, которая может задерживать выполнение программы на несколько секунд. Но в JavaScript такая функция отсутствует из-за его асинхронного характера. В этой статье мы рассмотрим как реализовать js sleep самостоятельно.


js sleep

setTimout и sleep в JavaScript

Для того, чтобы лучше понять проблему, посмотрите следующий код. Он делает запрос к API GitHub для получения пользовательских данных, затем выводит количество публичных репозиториев и, наконец, пошлет в консоль "Привет!"


JS
fetch('https://api.github.com/users/username')
  .then(res => res.json())
  .then(json => console.log(json.public_repos));
console.log("Привет!");

Но если запустить такой код, то сначала он выведет на экран "Привет!", а уже потом количество публичных репозиториев.

Так происходит, потому что получение данных от API — это асинхронная операция в JavaScript. Интерпритатор JavaScript встретит команду fetch и отправит запрос. Он не будет ждать завершения запроса и выведет "Привет!" в консоль, и потом через пару сотен миллисекунд выдаст количество рекозиториев.

Создаем простую задержку с помощью js setTimeout

Теперь, давайте рассмотрим создание задержки в JavaScript, используя метод setTimeout.


JS
console.log("Привет");
setTimeout(() => { console.log("мир"); }, 3000);

Этот код запишет в консоль "Привет", а затем через 3 секунды "мир" ‐ во многих случаях такой задержки достаточно. Но имейте ввиду, что в js setTimeout ‐ это асинхронный метод. Попробуйте изменить предыдущий код следующим образом:


JS
console.log("Привет");
setTimeout(() => { console.log("мир"); }, 3000);
console.log("Пока");

Этот код выведет: Привет Пока мир.

Вы также можете использовать setTimeout (или его брата setInterval), чтобы заставить JavaScript подождать пока не будет выполнено какое-либо условие. К примеру, вам нужно дождаться появления определенного элемента на странице:


JS
function waitForDOM () {
  const container = document.querySelector('container');

  if (container.length) {
    // Делаем что-то с контейнером
  } else {
    setTimeout(waitForDOM, 300); // Попробовать снова через 300 миллисекунд
  }
}

waitForDOM();

Управление потоком в современном JavaScript

В JavaScript часто бывают ситуации, когда вам нужно подождать, пока то-то произойдет, а затем сделать что-то в ответ. В примере выше мы использовали анонимную callback функцию. Но что если вам нужно подождать несколько событий? В этом случае синтаксис быстро становится довольно грубым.

К счастью, язык значительно изменился за последние несколько лет и теперь у нас есть новые конструкции для этих целей. К примеру, мы может переписать код для получения информации из API GitHub, используя async await.


JS
(async () => {
  const res = await fetch(`https://api.github.com/users/username`);
  const json = await res.json();
  console.log(json.public_repos);
  console.log("Привет!");
})();

Теперь код выполняется сверху вниз.

Sleep в JavaScript

Мы уже готовы остановить поток выполнения программы и заставить JavaScript спать. Вот как мы можем это сделать:


JS
function sleep(milliseconds) {
  const date = Date.now();
  let currentDate = null;
  do {
    currentDate = Date.now();
  } while (currentDate - date < milliseconds);
}

console.log("Привет");
sleep(2000);
console.log("мир");

В результате сначала в консоли отобразится "Привет", пауза на две секунды, а затем "мир". Функция работает с помощью метода Date.now, получает количество миллисекунд, прошедших с 1 января 1970 года, и присваивает это значение переменной date. Запускает цикл, который будет продолжаться, пока разница между date и currentDate будет меньше нужной задержки.

Улучшаем функцию js sleep

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


JS
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

console.log("Привет");
sleep(2000).then(() => { console.log("мир"); });

Этот код выведет в консоль "Привет", подождет 2 секунды, затем выведет "мир". Внутри мы используем Promise.

Сделаем JavaScript функцию sleep с помощью async ... await:


JS
function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function delayedGreeting() {
  console.log("Привет");
  await sleep(2000);
  console.log("мир");
}

delayedGreeting();
console.log("Пока");

Написать комментарий