InspectorDanno
InspectorDanno

Reputation: 995

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?

Upvotes: 2

Views: 38

Answers (4)

hackape
hackape

Reputation: 19947

You return that promise from drawLoop’s callback, that does not make animationFunction return promise. Fix like below:

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

  //init animation function stuff...

  let done;
  const promise = new Promise((resolve) => { done = resolve });

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

  return promise;
};

Upvotes: 1

Simon Bruneaud
Simon Bruneaud

Reputation: 2557

You are returning the Promise in the callback function of drawloop instead of animationFunction.

It should do the trick:

const animationFunction = (args) => {
  return new Promise((resolve, reject) => {
    const duration = 1000;

    //init animation function stuff...

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

Upvotes: 1

ggorlen
ggorlen

Reputation: 56865

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

Upvotes: 2

Milton
Milton

Reputation: 1012

Almost there, this will work:

const animationFunction = (args) => {
  return new Promise((resolve, reject) => {
  const duration = 1000;

  //init animation function stuff...

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

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

Upvotes: 1

Related Questions