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) // Сообщение: Прошла секунда