Борьба с обещанием реализации - PullRequest
1 голос
/ 01 мая 2020

У меня есть две функции. Первый - это 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() можно считать асинхронным, потому что требуется определенное время до l oop, прежде чем программа сможет продолжить. Я нашел способ использовать обратные вызовы, чтобы заставить dispatch() запускаться в родительской функции после того, как animationFunction() завершит цикл, но я запутался в том, как использовать реализацию, основанную на обещаниях. Вот мое решение для обратного вызова:

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

Но, похоже, это не сработало. Что я делаю не так?

Ответы [ 4 ]

2 голосов
/ 01 мая 2020

Вы возвращаете обещание не для вызывающего animationFunction, а для области drawLoop, где, вероятно, это не рассматривается (из вашего примера трудно сказать, так как большая часть кода отсутствует).

Вместо этого верните обещание от 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);
});
1 голос
/ 01 мая 2020

Вы возвращаете это обещание из обратного вызова drawLoop, которое не дает animationFunction возвращаемого обещания. Исправить, как показано ниже:

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;
};
1 голос
/ 01 мая 2020

Почти там, это будет работать:

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();
  });
}
1 голос
/ 01 мая 2020

Вы возвращаете Обещание в функции обратного вызова drawl oop вместо 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();
      }
    });
  }
};
...