Search code examples
javascriptes6-promise

Promise to change background color gone wrong


I am learning promises in JS, I have tried somethings accidentally, but then I ended up with doubts. I have mentioned what I expected from code in //comments. The actual change on web page was - after 1 sec backgroundColor gets red but there is no change in color afterwards!!

    const colorChange = (newColor) => {
        return new Promise((resolve, reject) => {
            resolve(newColor); // returns resolved promise without any delay
        })
    }
    
    colorChange("red")
        .then((newColor) => {
            setTimeout(() => {
                console.log('in 1st then ', newColor);
                document.body.style.backgroundColor = newColor;
                return colorChange("yellow"); // I think this will return a resolved promise after (1 sec from start)
            }, 1000);
        })
        .then((newColor) => { // I think after (1 sec from start) this will get executed
            setTimeout(() => {
                console.log('in 2nd then ', newColor); // I thought that this should be yellow, but it is undefined!! why?
                document.body.style.backgroundColor = newColor; // I think this will get executed after (2 sec from start)
            },1000);
        })

Console

in 1st then  red
in 2nd then  undefined

Can someone explain how this code ran?


Solution

  • Promise and setTimeout are asynchronous, returning something inside their callback will not affect outer function's return as it's execution is already completed.

    You can try like this if you want, resolving promise based on timer.

    const colorChange = (newColor, resolveAfter) => {
        return new Promise((resolve, reject) => {
          if (resolveAfter) {
              setTimeout(() => resolve(newColor), resolveAfter);
          } else {
            resolve(newColor); // returns resolved promise without any delay
          }
        })
    }
    
    colorChange("red")
    .then((newColor) => {
          console.log('in 1st then ', newColor);
          document.body.style.backgroundColor = newColor;
           //this will return a resolved promise after (1 sec from start)
        return colorChange("yellow", 1000);
    })
    .then((newColor) => { // after 1 sec from start this will get executed
        document.body.style.backgroundColor = newColor;
    })