Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

111
Vistas
How can I make the function in setTimeout execute completely?

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();

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

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.
about 4 years ago · Juan Pablo Isaza Denunciar

0

Ultimately you need to make your method fun be able to report when it is finished as it is an asynchronous method (calls setTimeout). The best way to do this is return a Promise which allows calls to use await on it

fun() {
    return new Promise(resolve => {    
      
      const exec = () => {
        if (this.a.getCnt() > 0) {
          this.a.real();
          setTimeout(exec.bind(this), 1000);
        }
        else{
          resolve();
        }
      }
      
      exec.apply(this);
    })
  }

Once you've done that, also mark function f as async which allows you to call await inside it:

async f() {
  await this.b.fun();
  console.log("end");
}

And then all works as expected:

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

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

  getCnt() {
    return this.cnt;
  }
}

class B {
  constructor() {
    this.a = new A();
  }
  fun() {
    return new Promise(resolve => {    
      
      const exec = () => {
        if (this.a.getCnt() > 0) {
          this.a.real();
          setTimeout(exec.bind(this), 1000);
        }
        else{
          resolve();
        }
      }
      
      exec.apply(this);
    })
  }
}

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

var c = new C();
c.f();

about 4 years ago · Juan Pablo Isaza Denunciar

0

I tried to write a generic function that emulate typing, hope this help you understand async/await functions

let fakeConsole = document.getElementById('console');

async function sleep(time) {
  await new Promise(r => setTimeout(r, time));
}

function type(text) {
  fakeConsole.innerHTML += text;
}

async function emulateTyping(text, speed) {
  // split the text into an array of characters;
  const characters = text.split('').reverse();
  if (characters.length > 0) {
    // display first character right away
    type(characters.pop());
    while (characters.length > 0) {
      // wait <speed> millisections
      await sleep(speed);
      // type one character
      type(characters.pop());
    }
  }
}

async function main() {
  // async function we wait for the end with "await"
  await emulateTyping("!!!!!", 500);
  // sync function
  type(' END');
};

main();
<pre id="console"></pre>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda