setTimeout()

setTimeout() в JavaScript - это функция или метод объекта window, позволяющий установить таймер, после отсчёта которого будет выполнена заданная функция. Задержка выставляется в миллисекундах, а отменить вызов можно с помощью clearTimeout().


Синтаксис

  
  setTimeout(() => {
    console.log('Прошло 3 секунды')
  }, 3000)
  

Функция в setTimeout() может быть анонимной, стрелочной, именованной, методом объекта или конструктором, а также строкой (что не рекомендуется).

Анонимная функция

  
  setTimeout(function() {
    console.log('Прошло 3 секунды')
  }, 3000)
  

Именованная функция

  
  function message() {
    console.log('Прошло 3 секунды')
  }
  
  setTimeout(message, 3000)
  

Передавая именованную функцию в setTimeout() обратите внимание, что запись происходит без скобок ().

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

  
  setTimeout("console.log('Прошло 3 секунды')", 3000)
  

Задержка

Задержка в setTimeout() задается в миллисекундах, если необходимо отсрочить выполнение кода на 1 секунду, пишем 1000, если на минуту - тогда 60000. Можно также записать и 0, но в большинстве браузеров код выполнится не сразу, а только через 4 миллисекунды. Максимальная задержка в setTimeout равна 2147483647 миллисекунд, это около 24.85 дней.

Также, работая с setTimeout(), стоит учитывать, что вызов функции произойдет не ровно через заданное количество времени: выполнение может задержаться.

  
  setTimeout(() => {
    console.log('Ну наконец-то');
  }, 1000);
  
  for (let i = 0; i <= 50000; i++) {
    console.log(i)
  }
  

Например, здесь фразу Ну наконец-то мы увидим в console не через секунду, а только после того, как отработает цикл for. Когда интерпретатор обработает setTimeout счетчик запустится, но спустя секунду сообщение мы не увидим, так как поток выполнения кода будет занят выводом в console цифр от 0 до 50000. Только после того, как здесь будет всё готово, мы сразу же увидим Ну наконец-то.

Если вкладка не активна продолжительное время, современные браузеры замедляют или даже прекращают выполнение JavaScript, в этом случае работа setTimeout может быть существенно замедлена или даже приостановлена.

Дополнительные параметры

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

  
  let startMessage = 'Прошло'
  let endMessage = '3 секунды'
  
  function printMessage(message1, message2) {
    console.log(`${message1} ${message2}`)
  }
  
  setTimeout(printMessage, 3000, startMessage, endMessage)
  

Используя анонимную функцию.

  
  setTimeout(function() {
    printMessage(startMessage, endMessage)
  }, 3000)
  

Тоже сработает

  
  setTimeout(function(message1, message2) {
    console.log(`${message1} ${message2}`)
  }, 3000, startMessage, endMessage)
  

Или стрелочную

  
  setTimeout(() => printMessage(startMessage, endMessage), 3000)
  

clearTimeout

Для отмены таймера, установленного с помощью setTimeout, используют функцию clearTimeout.

  
  let timerId = setTimeout(() => {
    console.log('Прошло 3 секунды')
  }, 3000)
  
  clearTimeout(timerId)
  console.log(timerId) // 1
  

Для начала, в переменную необходимо записать уникальный идентификатор, который возвращает setTimeout(). Далее используем эту переменную в clearTimeout. Таким образом строка Прошло 3 секунды в console выведена не будет. Для наглядности можно увидеть и сам идентификатор, в нашем случае это 1.

this и setTimeout

Рассмотрим, как контекст this ведет себя при работе с setTimeout() в разных ситуациях.

Именованная функция

  
  function message() {
    console.log(this)
  }
  
  setTimeout(message, 1000) // Window
  

this в именованной функции, вызываемой в setTimeout(), ссылается на глобальный объект window в браузерах и на global в Node.js.

Метод объекта

  
  const obj = {
    message: 'Прошла секунда',
    printMessage: function message() {
      console.log(`Сообщение: ${this.message}`)
    }
  }
  
  setTimeout(obj.printMessage, 1000) // Сообщение: undefined
  console.log(window.message) // undefined
  

В методе объекта, вызванного через setTimeout, this также будет ссылаться на глобальный объект window. Поэтому в нашем случае мы получим undefined, то же самое, что и при window.message.

Стрелочная функция

  
  const obj = {
    message: 'Прошла секунда',
    printMessage: function message() {
      setTimeout(() => {
          console.log(`Сообщение: ${this.message}`)
      }, 1000)
    }
  }
  
  obj.printMessage() // Сообщение: Прошла секунда
  

Стрелочные функции наследуют контекст из окружающей среды, в итоге мы получаем желаемый результат.

bind

Можно задать контекст выполнения явно.

  
  const obj = {
    message: 'Прошла секунда',
    printMessage: function message() {
      console.log(`Сообщение: ${this.message}`)
    }
  }
  
  setTimeout(obj.printMessage.bind(obj), 1000) // Сообщение: Прошла секунда
  

Анонимная функция

Также, получить желаемый контекст можно, обернув вызов в анонимную функцию.

  
  const obj = {
    message: 'Прошла секунда',
    printMessage: function message() {
      console.log(`Сообщение: ${this.message}`)
    }
  }
  
  setTimeout(function() {
      obj.printMessage()
  }, 1000) // Сообщение: Прошла секунда