Dúvida sobre o funcionamento do setTimeout dentro de um loop

Salve pessoal, sou iniciante no Javascript e estou com uma dúvida sobre o funcionamento do setTimeout dentro de um loop for. Nesse trecho de código abaixo, não era para o valor de “i” ser mostrado no console a cada 1 segundo? Mas quando executo esse loop é esperado 1 segundo pra mostrar o primeiro valor da variável e os outros valores decrementados são mostrados logo na sequência sem respeitar o tempo do setTimeout. Agraço desde já se alguém puder me explicar como isso funciona.

for (let i = 60; i >= 0; i--) {
    setTimeout(function () {
      console.log(i);
    }, 1000);
}

setTimeout não funciona da mesma forma que o sleep de outras linguagens (no qual ele pausa a execução durante certo tempo e só depois continua).

setTimeout simplesmente diz: “execute isso depois de X tempo”, mas a execução do código não é pausada.

Ou seja, primeiro você chama setTimeout com i igual a 60, dizendo para imprimir depois de 1 segundo.

Mas como a execução não é pausada, ele vai pra próxima iteração, com i igual a 59, dizendo pra imprimir depois de 1 segundo. Como o loop executa muito rápido, isso é praticamente “instantâneo”, ou seja, o “agendamento” do 60 para daqui a um segundo se dá quase no mesmo instante do 59, o que na prática faz com que eles sejam “agendados” para praticamente o mesmo “horário”. Por isso que não há um intervalo de 1 segundo entre eles.

Se a ideia era ter esse intervalo, basta adaptar para só chamar o próximo número depois que o atual for impresso:

function imprime(i) {
    console.log(i);
    if (i > 0)
        setTimeout(function() { imprime(i - 1); }, 1000);
}

imprime(60);

Exemplo adaptado daqui.


Leitura complementar: