How can I make the function in setTimeout execute completely?

Issue

New to js,I want to output 5 ‘!’s with a 1-second interval,and finally output "end".
I thought the problem was related to asynchronization.
I have tried a lot of times and a lot of methods such as "await,async" and "promise" ,but still failed.

class A {
  constructor() {
    this.cnt = 5;
  }

  real() {
    this.cnt--;
    console.log("!");
  }

  getCnt() {
    return this.cnt;
  }
}

class B {
  constructor() {
    this.a = new A();
  }
  fun() {
    if (this.a.getCnt() > 0) {
      this.a.real();
      setTimeout(() => this.fun(), 1000);
    }
  }
}

class C {
  constructor() {
    this.b = new B();
  }
  f() {
    this.b.fun();
    console.log("end");
  }
}
var c = new C();
c.f();

Solution

Skipping the complexity of the 3 classes involved, this is elegantly solved with async functions. (Without async functions, the cascade of setTimeouts in a loop becomes more difficult to manage.)

This can of course be wrapped into a trio of classes if required.

// Turns `setTimeout` into a promise you can `await`.
async function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// Calls a function `fun` `times` times, delaying for `delayTime` ms between each invocation.
// Since this is an async function, it returns a promise that will resolve as soon as it's done,
// which in turn can be awaited upon.
async function repeatWithDelay(fun, times, delayTime) {
  for (let i = 0; i < times; i++) {
    await fun(i);
    await delay(delayTime);
  }
}

// Prints the number passed in (could just print an exclamation mark).
function print(i) {
  console.log(`${i}!`);
}

async function main() {
  console.log("Go!");
  await repeatWithDelay(print, 5, 500);
  console.log("Done!");
}

// Assumes top-level `await` is not available in your environment.
// If it is, this too can be replaced with a simple `await`.
main().then(() => {
  console.log("Main done.");
});

This prints out

Go!
0!
1!
2!
3!
4!
Done!
Main done.

Answered By – AKX

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published