Implicit promises

Shouldn’t delayedColorChange() return a promise passed to it by the anonymous arrow function it houses. Which subsequently in rainbow(), according to my flawed understanding anyway, is waited until resolved or rejected?

It’s currently not waiting but going straight to ‘orange’?!

const  delayedColorChange = async (newColor, delay) => {
    setTimeout(() => {
        document.body.style.backgroundColor = newColor
    }, delay)
}

async function rainbow() {
    await delayedColorChange('red', 1000)
    delayedColorChange('orange', 1000)
}

console.log(rainbow())

I do have a solution for this below but I 'd like to know where I’m going wrong above in my understanding of promises.

const delayedColorChange = (newColor, delay) => {
    return new Promise((resolved, rejected) => {
        setTimeout(() => {
            document.body.style.backgroundColor = newColor
            resolved();
        }, delay)
    })
}

You’re not awaiting the second call (the one with “orange”), so it doesn’t go into the queue behind the first one.

I’m not sure what you mean exactly so I tried this which tbh didn’t make sense as from what I understand the code in rainbow() shouldn’t progress before the first call finishes.

async function rainbow() {
    await delayedColorChange('red', 1000)
    await delayedColorChange('orange', 1000)
}

Ah, sorry I didn’t look at the code, I thought you were still using the promise version of delayedColorChange (and it should work the way you expect it to with your original code if you did have it promisified).

It does happen, it just happens at effectively the same time, setTimeout doesn’t return a promise so it doesn’t matter if you put that version of delayedColorChange in an async function or not, or you put await before it or not, you tell to JS run two setTimeouts in two functions, and JS runs them one after the other as specified. Each one has a 1sec timeout, and the red one is first so after a 1sec the background goes red then orange.

Well that’s what I’m trying to figure out why I don’t get red for 1 second then orange. When I run the code below it just goes straight to orange?!

const  delayedColorChange = async (newColor, delay) => {
    setTimeout(() => {
        document.body.style.backgroundColor = newColor
    }, delay)
}

async function rainbow() {
    await delayedColorChange('red', 1000)
    delayedColorChange('orange', 1000)
}

console.log(rainbow())

No, it goes red → orange. You have two functions. They execute one after the other. The first one has a function in a setTimeout that executes and changes the background to red after one second. Second one has a function in a setTimeout that executes and changes the background to orange after one second. So first one executes, then the second one executes. Then one second later, the callback functions passed to setTimeout execute for each one – the background changes to red then it changes to orange, as specified. This happens far too fast to be able to see it, but it does happen.

function colorChange(newColor) {
  document.body.style.backgroundColor = newColor
}

function rainbow() {
  colorChange("red");
  colorChange("orange");
}

:point_up_2: In this version, the colour changes to red, then it changes to orange with no delay.

function delayedColorChange(newColor, delay) {
  setTimeout(() => {
    document.body.style.backgroundColor = newColor
  }, delay);
}

function rainbow() {
  delayedColorChange("red", 1000);
  delayedColorChange("orange", 1000);
}

:point_up_2: In this version, there is a timeout of a second, then the colour changes to red, then it changes to orange.

async function delayedColorChange(newColor, delay) {
  setTimeout(() => {
    document.body.style.backgroundColor = newColor
  }, delay);
}

async function rainbow() {
  await delayedColorChange("red", 1000);
  await delayedColorChange("orange", 1000);
}

:point_up_2: In this version exactly the same happens: there is a timeout of a second, then the colour changes to red, then it changes to orange.


So this function:

async function delayedColorChange

This returns a promise. So with

async function rainbow() {
  await delayedColorChange("red", 1000);
  delayedColorChange("orange", 1000);
}

You are saying

"run delayedColorChange then once that has resolved run the next delayedColorChange".

Which happens, the first one runs, resolves, the second one runs. The result is that a second later, the colour goes to red, then it goes to orange. That they are async is irrelevant in the example here: the functions execute almost instantaneously, then the result of the setTimeout occurs a second later, so whether they’re async or not makes no visible difference.

What you aren’t saying is

"run delayedColorChange then once the callback function from setTimeout has resolved after the delay run the next delayedColorChange"

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.