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.