javascript - Como alterar o tempo do intervalo dinamicamente no loop for de acordo com o número de índice/iteração?




wait (5)

Aqui está uma função que será exibida imediatamente, depois 1 segundo depois, 2 segundos depois, 3 segundos depois etc. Nenhuma matemática especial, nenhuma promessa necessária

const n = 5;
let cnt=0;

function show() {
  console.log("call "+cnt,"delay: ",cnt,"sec");
  cnt++;
  if (cnt > n) return; // we are done
  setTimeout(show, cnt*1000 ); // cnt seconds later
}
show()

Como não pude comentar, sou forçado a escrever este post. Eu recebi o código abaixo que atrasa / espera exatamente 1 segundo ou 1000 milissegundos -

let n = 5;
for (let i=1; i<n; i++)
{
  setTimeout( function timer()
  {
      console.log("hello world");
  }, i*1000 );
}

Mas como posso atrasá-lo i * 1000 segundos em vez de 1000 milissegundos fixos para que a espera dependa do número da iteração?

Por exemplo, se n = 5, quero o atraso do loop 1 segundo na 1ª iteração. 2 segundos na segunda iteração e assim por diante .. o atraso final será de 5 segundos.


Embora essa tarefa possa ser resolvida com promessas, fluxos reativos e outras ferramentas interessantes (ei, ninguém sugeriu o uso de trabalhadores ainda!), Ela também pode ser resolvida com um pouco de aritmética.

Portanto, você deseja tempos limite em uma sequência: 1s, o anterior + 2s, o anterior + 3s e assim por diante. Essa sequência é: 1, 3, 6, 10, 15 ... e sua fórmula é a[n] = n * (n + 1) / 2 . Sabendo que...

let n = 6;
console.log(new Date().getSeconds());

for (let i = 1; i < n; i++) {
  setTimeout(function timer() {
    console.log(new Date().getSeconds());
  }, 1000 * i * (i + 1) / 2);
}


O loop não espera que a função de tempo limite seja concluída. Portanto, quando o loop é executado, ele agenda seu alerta para cada índice.

Você pode usar uma função que será executada de acordo com o seu índice, mas agendada ao mesmo tempo. Você pode sentir a diferença de 3 segundos.

function test(i){
    setTimeout( function timer(){
        console.log("hello world" + i);
    }, i*3000);
}
for (let i=1; i<4; i++) {
   test(i);
}

Use chamadas recursivas em vez de loop for

let i=1;
function a(i) {
  if (i > 5)
    return
  else
    b("message", i)
}

function b(s, f) {
  setTimeout(function timer() {
    console.log(s + " " + f + " seconds");
  }, f * 1000);
  a(++i);
}
a(i);


EXPLORANDO A Resposta de @mbojko

for (let i = 1; i <= 5; i++) {
  setTimeout(function timer() {
    console.log("Delaying - " + i + " seconds");
  }, 1000 * i * (i + 1) / 2);
}

function Explanation(){
  //This comes from the finite arithmetic series n(n+1)/2
            //http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/runsums/triNbProof.html
            //for first five iterations..
            //1000 * 1 * (1+1)/2 = 1
            //1000 * 2 * (2+1)/2 = 3
            //1000 * 3 * (3+1)/2 = 6
            //1000 * 4 * (4+1)/2 = 10
            //1000 * 5 * (5+1)/2 = 15
}





wait