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

365
Views
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 answers
Answer question

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 Report

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 Report

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 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!