• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

159
Vistas
Crea una promesa aquí, resuélvela allá

Pensé que tenía el truco de las promesas en todas las situaciones, pero estoy atascado aquí: me gustaría que una animación sucediera con un temporizador. Lo único que puedo obtener del paquete de gráficos es el número de cuadro, por lo que calculo un cuadro final en función de una estimación de velocidad de cuadro.

El paquete de gráficos es p5.js , que expone frameCount , que solo se ejecuta a unos 60 fps en cada ciclo de dibujo. (Lo nombré currentFrame en esta pregunta, con la esperanza de que eso se aclarara). Por lo que puedo decir, esta es la única visibilidad que tengo en el estado del cuadro de animación en p5.js

 doAnimation(duration) { // animation stuff this.endFrame = currentFrame + (60 * duration); // 60fps seems to be a good guess } draw() { if (currentFrame < this.endFrame) { // compute and draw the state of the animation } else if (currentFrame >= this.endFrame) { // animation done } }

Lo que me desconcierta es cómo darle a la persona que llama a doAnimation una promesa que se resuelva en el otro método. He intentado esto:

 doAnimation(duration) { // animation stuff this.endFrame = currentFrame + (60 * duration); this.animationPromise = new Promise(resolve => { // I realize this is wrong, but it illustrates the problem. How do I run this test later? if (currentFrame >= this.endFrame) resolve(); }); return this.animationPromise; } draw() { if (currentFrame < this.endFrame) { // compute and draw the state of the animation } else if (currentFrame >= this.endFrame) { this.animationPromise.resolve(); // also wrong, I think // since resolve isn't an instance method of a promise } }

¿Alguien puede deshacerme de esto?

about 3 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

En lugar de almacenar la promesa de resolución, debe almacenar la resolución para llamar:

 doAnimation(duration) { // animation stuff this.endFrame = currentFrame + (60 * duration); return new Promise(resolve => { this.onAnimationFinished = resolve; }); } draw() { if (currentFrame < this.endFrame) { // compute and draw the state of the animation } else if (currentFrame >= this.endFrame) { this.onAnimationFinished(); } }

Por supuesto, debe asegurarse de que solo haya una llamada a doAnimation() a la vez, y que no se llame a draw( draw() antes doAnimation() (o más precisamente, que onAnimationFinished esté configurado cuando se configure un endFrame ). También es posible que desee restablecerlos (a undefined ) una vez que se alcance el marco final.

about 3 years ago · Juan Pablo Isaza Denunciar

0

En general, el cumplimiento o el rechazo de una promesa debe hacerlo el proceso que se inició dentro de la función ejecutora que aprobó new Promise . Es muy raro necesitar cumplir o rechazar la promesa desde fuera (al menos, de manera que la persona que llama se dé cuenta de que es un cumplimiento de promesa).

Yo usaría una cola de devolución de llamada:

  1. Mantenga una lista de animaciones pendientes que tenga el cuadro en el que terminan y una devolución de llamada.

  2. Haga que draw busque en la cola las devoluciones de llamada de animación que debería llamar en función del (nuevo) currentFrame .

  3. Haga que el código doAnimation en cola una devolución de llamada

Apenas:

 activeAnimations = []; doAnimation(duration) { // animation stuff const endFrame = currentFrame + (60 * duration); // 60fps seems to be a good guess return new Promise(resolve => { this.activeAnimations.push({ endFrame, done: resolve, // Or possibly: `done: () => resolve()` // so this code is in control of whether // there's a fulfillment value }); }); } draw() { for (let index = 0; index < this.activeAnimations; ++index) { const animation = this.activeAnimations[index]; if (currentFrame > animation.endFrame) { // Animation done animation.done(); this.activeAnimations.splice(index, 1); --index; } else { // Continue animation } } }

El motivo del comentario done: () => resolve() es que, en general, trato de evitar exponer directamente las funciones de resolve / reject de la promesa al código fuera del ejecutor de la promesa, sobre la base de que el código fuera de él normalmente no debería ser directamente en el control de lo que sucede con la promesa. (Hago una excepción para setTimeout . :-) ) Pero eso puede ser excesivo aquí.

about 3 years ago · Juan Pablo Isaza Denunciar

0

Como alternativa, también puede asignar para draw dentro de la devolución de llamada del constructor de la promesa:

 function basicDraw() { // ... } var draw = basicDraw; // Default function doAnimation(duration) { // animation stuff this.endFrame = currentFrame + (60 * duration); return new Promise((resolve) => { draw = () => { basicDraw(); if (currentFrame < this.endFrame) { // compute and draw the state of the animation } else if (currentFrame >= this.endFrame) { draw = basicDraw; // back to normal resolve(); } }; }); } doAnimation(1000).then(() => { /* whatever you want to do next */ });
about 3 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda