Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

114
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda