Home > Software engineering >  Callback after timeouts have been finished to execute
Callback after timeouts have been finished to execute

Time:09-19

My main function is play(). This will call first easeInOut.

I have a function called easeInOut that uses setTimeout. This will also call a nested function. (toggleFade). I want to call spawnBug only after easeInOut function has finished. (this is because easeInOut will set some width and height for a div and set its display to flex. I need it to be completed in order to use clientWidth and clientHeight for that div, having now display: flex).

function easeInOut(elementOut, elementIn, fadeTime) {
elementOut.classList.toggle("fade");
setTimeout(() => {
    elementOut.style.display = "none";
    toggleFade(elementIn);
}, fadeTime);

function toggleFade(elemIn) {
    elemIn.style.display = "flex"; // this will make div clientWidth/Height available
    setTimeout(() => {
        elemIn.classList.toggle("fade");
    }, fadeTime);
}}

Main function:

function play() {
easeInOut(selectContainer, gameInterface, 100);
spawnBug(100);  // i want this to be executed only when the above function has finished
} 

CodePudding user response:

Simplest way is to use Promise and async/await

function easeInOut(elementOut, elementIn, fadeTime) {
  return new Promise(resolve => {
    elementOut.classList.toggle("fade");
    setTimeout(() => {
      elementOut.style.display = "none";
      toggleFade(elementIn);
    }, fadeTime);

    function toggleFade(elemIn) {
      elemIn.style.display = "flex"; // this will make div clientWidth/Height available
      setTimeout(() => {
        elemIn.classList.toggle("fade");
        resolve();
      }, fadeTime);
    }
  });
}

async function play() {
  await easeInOut(selectContainer, gameInterface, 100);
  spawnBug(100); // i want this to be executed only when the above function has finished
}

Expanding the use of async/await and Promises, you can make the code even more readable

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

async function easeInOut(elementOut, elementIn, fadeTime) {
    elementOut.classList.toggle("fade");
    await wait(fadeTime);
    elementOut.style.display = "none";
    
    elemIn.style.display = "flex";
    await wait(fadeTime);
    elemIn.classList.toggle("fade");
}

async function play() {
    await easeInOut(selectContainer, gameInterface, 100);
    spawnBug(100); // i want this to be executed only when the above function has finished
}
  • Related