努力实现承诺

Struggling with promise implementation

我有两个功能。第一个是 animationFunction() 运行 一段时间。第二个是 parentFunction(),它需要一个名为 dispatch() 的函数在 animationFunction() 停止循环后变为 运行。 dispatch() 只能从父函数调用:

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

我觉得animationFunction()可以认为是异步的,因为它需要一定的循环时间,程序才能进行。在 animationFunction() 完成循环后,我想出了一种使用回调在父函数中将 dispatch() 获取到 运行 的方法,但我对如何使用基于承诺的实现感到困惑。这是我的回调解决方案:

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

我对基于 Promise 的解决方案感到困惑。我试过这样做:

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

但这似乎不起作用。我做错了什么?

您正在 drawloop 的回调函数中返回 Promise 而不是 animationFunction。

它应该可以解决问题:

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

您 return 承诺的不是 animationFunction 的调用者,而是可能未处理的 drawLoop 范围(很难从您的示例中看出,因为大多数代码都丢失了)。

相反,return 来自 animationFunction 的承诺和 resolve 它在计时器启动时的承诺。这是一个最小的、可重现的例子:

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

你 return 从 drawLoop 的回调中承诺,这并没有使 animationFunction return 承诺。修复如下:

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