Search code examples
javascriptpromisees6-promise

Struggling with promise implementation


I have two functions. The first is an animationFunction() that runs for a certain amount of time. The second is a parentFunction() that needs a function called dispatch() to be run after the animationFunction() has stopped looping. dispatch() can only be called from the parent function:

const animationFunction = (args) => {
  const duration = 1000;

  //init animation function stuff...

  //draw loop
  const loop = drawLoop(({ time }) => {
    if (time > duration) {
      loop.stop();
    }
  });
};

const parentFunction = () => {
  animationFunction(args);
  //dispatch be run after animationFunction is done looping
  dispatch(); 
}

I think animationFunction() can be thought of as asynchronous, because it requires a certain amount of time to loop before the program can proceed. I figured out a way using callbacks to get dispatch() to run in the parent function after animationFunction() is done looping, but I'm confused on how to use a promise-based implementation. Here's my callback solution:

const animationFunction = (args, callback) => {
  const duration = 1000;

  //init animation function stuff...

  //draw loop
  const loop = drawLoop(({ time }) => {
    if (time > duration) {
      loop.stop();
      callback();
    }
  });
};

const parentFunction = () => {
  animationFunction(args, () => {
    //dispatch should be run after animationFunction is done looping
    dispatch();
  }); 
}

I'm confused about the Promise-based solution. I tried doing this:

const animationFunction = (args) => {
  const duration = 1000;

  //init animation function stuff...

  //draw loop
  const loop = drawLoop(({ time }) => {
    if (time > duration) {
      loop.stop();
      return new Promise((resolve, reject) => {
        resolve();
      });
    }
  });
};

const parentFunction = () => {
  animationFunction(args).then(() => {
    dispatch();
  });
}

But this didn't seem to work. What am I doing wrong?


Solution

  • You're returning the promise not to animationFunction's caller but to the drawLoop scope where it's probably not dealt with (it's hard to tell from your example since most of the code is missing).

    Instead, return a promise from animationFunction and resolve it when the timer is up. Here's a minimal, reproducible example:

    const animationFunction = () => {
      const duration = 10;
      let ticks = 0;
      return new Promise((resolve, reject) => {
        (function update() {
          console.log(ticks++);
    
          if (ticks >= duration) {
            return resolve("some optional data");
          }
    
          requestAnimationFrame(update);
        })();
      });
    };
    
    animationFunction().then(data => {
      console.log("dispatched: " + data);
    });