Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

369
Visualizações
can you resolve a promise in an if statement?

I'm quite new to using promises in JS, and im trying to have a function execute before executing some more code in another function. Only issue is that the promised function uses an if statement to loop a setTimeout command. I added an if statement to make sure the function is done looping before i resolve the promise but the resolve just isn't doing anything. I used console.log to make sure that the if statement is executing and it has no problems printing to the console on either side of the resolve. Any help would be greatly appreciated.

Code:

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 Respostas
Responde à pergunta

0

After the first setTimeout callback executes, you will never resolve the outermost call's returned promise. You will resolve the innermost call's returned promise eventually, but that does nothing since the promise returned from there is never used.

You could write if (this.state < setting) resolve(this.changeTexture(loader, setting)) but I'd recommend a different, far less confusing (and non-recursive) way instead:

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

Here I've made the changeTexture function async as well, so we can use await inside and therefore implement the delay in a more straight-forward manner and can build a regular while loop around the whole thing.

(Note: Technically your existing code does the first iteration unconditionally, so a do ... while would be more accurate, but I'm assuming that is just a result of the way you tried building it with setTimeout and not really what you need.)

over 4 years ago · Santiago Trujillo Relatório

0

You can as long as there is a closure linking the resolve variable in the Promise constructor with the resolve() you call in your if statement. However in your code you don't have this:

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.

This means that when the if/else finally calls resolve() that resolve has nothing to do with the Promise you returned when you call changeTexture().

The way to do what you want is to not call changeTexture recursively so that you maintain a closure between the Promise's resolve variable and the resolve you finally call. To do this simply separate your setTimeout callback from the main changeTexture function:

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

Alternatively for minimal change in code you can get your code working by changing only one line:

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

The arguments.callee variable points to the () => {... function you pass to setTimeout. However, arguments.callee is deprecated and is disabled in strict mode so use the loop function above if possible.

over 4 years ago · Santiago Trujillo Relatório

0

You can call resolve and reject from anywhere in your code you wish. But you must call exactly one of them exactly once from within your Promise.

Your sample code doesn't do that when your if-condition is false, so you need to fix that.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda