Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

362
Views
¿Puedes resolver una promesa en una declaración if?

Soy bastante nuevo en el uso de promesas en JS, y estoy tratando de ejecutar una función antes de ejecutar más código en otra función. El único problema es que la función prometida usa una declaración if para ejecutar un comando setTimeout. Agregué una declaración if para asegurarme de que la función haya terminado antes de resolver la promesa, pero la resolución simplemente no está haciendo nada. Utilicé console.log para asegurarme de que la declaración if se está ejecutando y no tiene problemas para imprimir en la consola en cualquier lado de la resolución. Cualquier ayuda sería muy apreciada.

Código:

 async makeToast(loader, toaster){ toaster.texture = loader.resources['toaster_down'].texture; this.interactive = false; this.x = toaster.x; this.y = toaster.y - 100; let transform = {y: this.y}; let popDown = new TWEEN.Tween(transform) .to({y: toaster.y - 50}, 200) .onUpdate(() => this.y = transform.y); popDown.start(); await this.changeTexture(loader, toaster.setting) console.log('toasting done'); this.interactive = true; } changeTexture(loader, setting){ return new Promise((resolve, reject) => { setTimeout(() => { this.state++; this.texture = loader.resources[`bread${this.state}`].texture; if(this.state < setting) this.changeTexture(loader, setting); else if(this.state == setting) resolve(); }, 1000); }); }
over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Después de que se ejecute la primera devolución de llamada setTimeout , nunca resolverá la promesa devuelta de la llamada más externa. Eventualmente resolverá la promesa devuelta de la llamada más interna , pero eso no hace nada ya que la promesa devuelta desde allí nunca se usa.

Podría escribir if (this.state < setting) resolve(this.changeTexture(loader, setting)) pero recomendaría una manera diferente, mucho menos confusa (y no recursiva) en su lugar:

 // This could be defined globally, can be useful elsewhere too const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
 // This is in your object async changeTexture (loader, setting) { while (this.state < setting) { await delay(1000) this.state++ this.texture = loader.resources[`bread${this.state}`].texture } }

Aquí también he hecho que la función changeTexture async , por lo que podemos usar await inside y, por lo tanto, implementar el retraso de una manera más directa y podemos construir un ciclo while regular alrededor de todo.

(Nota: técnicamente, su código existente hace la primera iteración incondicionalmente, por lo que un do ... while sería más preciso, pero supongo que es solo el resultado de la forma en que intentó construirlo con setTimeout y no realmente lo que necesita .)

over 4 years ago · Santiago Trujillo Report

0

Puede, siempre que haya un cierre que vincule la variable de resolve en el constructor de Promise con la resolve() que llama en su declaración if . Sin embargo, en tu código no tienes esto:

 class SomeClass { // ... changeTexture(loader, setting){ return new Promise((resolve, reject) => { setTimeout(() => { this.state++; this.texture = loader.resources[`bread${this.state}`].texture; if(this.state < setting) this.changeTexture(loader, setting); <----------. else if(this.state == setting) | resolve(); <-- There is a closure to this / }, 1000); / }); .---------------------------' } | } However this function call will have it's own "resolve" variable that is no longer captured by this closure.

Esto significa que cuando if/else finalmente llama a resolve() esa resolución no tiene nada que ver con la Promesa que devolviste cuando llamas a changeTexture() .

La forma de hacer lo que quiere es no llamar a changeTexture de forma recursiva para mantener un cierre entre la variable de resolve de Promise y la resolve que finalmente llama. Para hacer esto, simplemente separe su devolución de llamada setTimeout de la función principal changeTexture :

 class SomeClass { // ... changeTexture(loader, setting){ return new Promise((resolve, reject) => { let loop = () => { // use arrow function to capture "this" this.state++; this.texture = loader.resources[`bread${this.state}`].texture; if(this.state < setting) setTimeout(loop, 1000); else if(this.state == setting) resolve(); } loop(); }); } }

Alternativamente, para un cambio mínimo en el código, puede hacer que su código funcione cambiando solo una línea:

 class SomeClass { // ... changeTexture(loader, setting){ return new Promise((resolve, reject) => { setTimeout(() => { this.state++; this.texture = loader.resources[`bread${this.state}`].texture; if(this.state < setting) setTimeout(arguments.callee(),1000); // <----THIS else if(this.state == setting) resolve(); }, 1000); }); } }

La variable arguments.callee apunta a la función () => {... que pasa a setTimeout . Sin embargo, arguments.callee está en desuso y está deshabilitado en modo estricto, así que use la función de loop anterior si es posible.

over 4 years ago · Santiago Trujillo Report

0

Puede llamar a resolve y reject desde cualquier lugar de su código que desee. Pero debe llamar exactamente a uno de ellos exactamente una vez desde dentro de su Promesa.

Su código de muestra no hace eso cuando su condición if es falsa, por lo que debe corregirlo.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!