JavaScript Timers
setTimeout()
Quando estiver escrevendo código JavaScript, você pode querer aplicar um delay na execução de uma função.
Esse é o trabalho da função setTimeout. Você especifica uma função de callback para ser executada mais tarde, e um valor em milisegundos especificando o quão mais tarde ela deve rodar:
setTimeout(() => {// roda após 2 segundos}, 2000)setTimeout(() => {// roda após 50 milisegundos}, 50)
Essa sintaxe define uma nova função. Você pode chamar qualquer outra função que quiser, ou passar o nome de uma função existente, e definir os parâmetros:
const myFunction = (firstParam, secondParam) => {// faz algo}// roda após 2 segundossetTimeout(myFunction, 2000, firstParam, secondParam)
setTimeout retorna o código de identificação do timer. Geralmente esse código não é usado, mas você pode guardá-lo, e "limpar" o timer se você quiser desagendar a execução daquela função:
const id = setTimeout(() => {// deve rodar daqui 2 segundos}, 2000)// mudei de ideia :vclearTimeout(id)
Delay de zero
Se você espeficiar o delay do timeout como 0, a função de callback será executada assim que possível, mas só depois da execução das funções correntes:
setTimeout(() => {console.log('depois ')}, 0)console.log(' antes ')
imprime antes depois.
Isso é especialmente útil para evitar bloqueio da CPU em tarefas intensas e deixar outras funções serem executadas enquanto são feitos cálculos pesados, enfileirando funções no fluxo.
Alguns browsers (IE e Edge) implementam um método chamado
setImmediate()que tem a exata mesma funcionalidade, mas não é padronizado e indisponível em outros navegadores. Porém é um método padrão no Node.js.
setInterval()
setInterval é uma função similar ao setTimeout, mas com uma diferença: em vez de rodar a função de callback uma vez, ela será rodada pra sempre, a cada intervalo de tempo especificado (em milisegundos):
setInterval(() => {// roda a cada 2 segundos}, 2000)
A função abaixo roda a cada 2 segundos até que você a diga pra parar, usando clearInterval, passando o identificador retornado por aquele setInterval:
const id = setInterval(() => {// roda a cada 2 segundos}, 2000)clearInterval(id)
É comum chamar o clearInterval dentro da função de callback do setInterval, para auto-determinar se ele deve rodar de novo ou parar. Por exemplo, esse código roda algo a não ser que o valor de App.somethingIWait seja arrived:
const interval = setInterval(() => {if (App.somethingIWait === 'arrived') {clearInterval(interval)return}// caso contrário, executa o conteúdo restante}, 100)
setTimeout recursivo
O setInterval inicia uma função a cada n milisegundos, sem levar em consideração quando uma função finalizou sua execução.
Se uma função gasta sempre o mesmo espaço de tempo, show de bola:
Talvez a função gaste tempos diferentes de execução, dependendo das condições da internet por exemplo:
E talvez uma longa execução sobreponha a próxima:
Para evitar isso, você pode agendar um setTimout recursivo para ser chamado quando a função de callback finaliza:
const myFunction = () => {// faz algosetTimeout(myFunction, 1000)}setTimeout(myFunction, 1000)
Pra chegar nesse cenário:
setTimeout e setInterval estão disponívels no Node.js, através do módulo Timers.
O Node.js também disponibiliza o setImmediate(), que é o equivalente de usar setTimeout(() => {}, 0), normalmente utilizado para trabalhar com o Event Loop do Node.js.