Jak zrobić taką pętle

0

Witam. Jak zrobić pętle która będzie odliczała od 0 do 100 ale że cyfry będą się powiększać co sekunde. Myśle że może dałoby to rade zrobić setTimeout albo async await ale jak ?

6

Np tak:

const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))

const count = async () => {
    for (let i = 0; i < 100; i++) {
        console.log(i) // you can change this to whatever
        await delay(1000)
    }
}

count()
3

Do takiego prostego zastosowania wystarczy pod setTimeout podstawić liczbę milisekund pomnożoną przez liczbę w pętli.

for (let i = 0; i <= 100; i++) {
   setTimeout(() => {
     console.log(i);
  }, 1000 * i);
}
2

Różnie można do tego podejść. Np. można zrobić funkcję, która za każdym uruchomieniem zwiększa licznik i jeśli licznik jest mniejszy od danej liczby, to wywołuje setTimeout z odpowiednim opóźnieniem:

let c = 0;
(function foo() {
   console.log(c);
   if (++c <= 100) setTimeout(foo, 1000);
})();

Ale jeśli masz więcej takich rzeczy do zrobienia, to wtedy wygodniej użyć async/await (przy takim małym kawałku kodu to nie ma znaczenia, ale przy większych rzeczach rozwiązania oparte na zwykłych callbackach będą po prostu nieczytelne).

0

Może po prostu setInterval z 1000ms zamiast setTimeout i w odpowiednim momencie wyczyścić timer, żeby nie liczył w nieskończoność. Prostsze rozwiązanie, mniej próbowania zrobienia na siłę setInterval z setTimeout.

1

@Aisekai: Pomijając już samą potrzebę czyszczenia interwałów - setTimeout w pętli / rekursywny i setIntervel to nie jest dokładny zamiennik. setIterval scheduluje wywołania na konkretny czas, setInterval umożliwia stałe odstępy czasowe pomiędzy wywołaniami, niezależnie od tego ile czasu zajmują operacje w pojedynczym cyklu.

Przykład:

const timeExpensiveOperation = () => {
  return new Array(1e6).fill(0).map((_, i) => i ** 2);
};

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const count1 = async () => {
  return new Promise((resolve) => {
    let counter = 0;
    let start = performance.now();

    const handle = setInterval(() => {
      const timeBetween = performance.now() - start;

      timeExpensiveOperation();
      counter++;
      console.log(counter, `Time between (setInterval 100): ${timeBetween.toFixed(2)} ms`);

      if (counter === 10) {
        clearInterval(handle);
        resolve();
      }

      start = performance.now();
    }, 100);
  });
};

const count2 = async () => {
  let counter = 0;
  let start = performance.now();

  while (counter < 10) {
    await delay(100);
    const timeBetween = performance.now() - start;

    timeExpensiveOperation();
    counter++;
    console.log(counter, `Time between (setTimeout 100): ${timeBetween.toFixed(2)} ms`);
    start = performance.now();
  }
};

const main = async () => {
  console.log('\nsetInterval:')
  await count1();
  console.log('\nsetTimeout:')
  await count2();
};

main();

Wyniki będą bardzo różne:

setInterval:
1 "Time between (setInterval 100): 100.30 ms"
2 "Time between (setInterval 100): 13.80 ms"
3 "Time between (setInterval 100): 23.40 ms"
4 "Time between (setInterval 100): 26.80 ms"
5 "Time between (setInterval 100): 0.80 ms"
6 "Time between (setInterval 100): 6.30 ms"
7 "Time between (setInterval 100): 0.10 ms"
8 "Time between (setInterval 100): 27.60 ms"
9 "Time between (setInterval 100): 19.60 ms"
10 "Time between (setInterval 100): 20.10 ms"

setTimeout:
1 "Time between (setTimeout 100): 100.40 ms"
2 "Time between (setTimeout 100): 100.30 ms"
3 "Time between (setTimeout 100): 100.20 ms"
4 "Time between (setTimeout 100): 100.20 ms"
5 "Time between (setTimeout 100): 100.70 ms"
6 "Time between (setTimeout 100): 100.30 ms"
7 "Time between (setTimeout 100): 100.30 ms"
8 "Time between (setTimeout 100): 100.20 ms"
9 "Time between (setTimeout 100): 100.30 ms"
10 "Time between (setTimeout 100): 100.40 ms"

Często zależy nam na tym drugim zachowaniu, co mój przykład uwzględnia. Za pomocą setTimeout da się zasymulować setInterval (zabacz przykład @Xarviel), ale w drugą stronę to już nie bardzo.

Oczywiście w przypadku OP nie ma to znaczenia - oba zadziałają niemal identycznie, uzasadniam tylko, czemu odruchowo użyłem setTimeout.

1 użytkowników online, w tym zalogowanych: 0, gości: 1