0

I need to display few messages of an array after 3 seconds utilizing array.map(). Here is the array:

const messages = [
    'hello', 'world', 'have', 'some', 'code'
]

In order to wait in the map i've created a wait function.

const wait = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(true)
    }, 3000)
})

Then, i have an app method where i've executed the Promise.all() like this,

const app = async () => {
    await Promise.all(messages.map(async msg => {
        await wait
        document.querySelector('#app').innerHTML += msg + ', '
    }))
}

app()

Expected output would be to wait for 3 seconds in every iteration of the map on the message array, but it will output all the messages at once after 3 seconds!

Codepen: https://codepen.io/rakibtg/pen/xQMwYK

What i'm missing here?

rakibtg
  • 5,521
  • 11
  • 50
  • 73
  • 2
    Once 3 seconds has passed `wait` is resolved... and awaiting it will complete immediately. You probably want a function to return a new promise each time. – Gerrit0 Dec 01 '18 at 05:34
  • 2
    It sounds like you're hoping for a sequence behavior? Promise.all() is good for doing something _after_ a group of async work finishes, but doesn't sound like the right fit here. – stealththeninja Dec 01 '18 at 05:35
  • @stealththeninja Yes, i'm hoping for a sequence behavior – rakibtg Dec 01 '18 at 05:37
  • @Gerrit0 `wait` now should return a function each time, but works the same way. https://codepen.io/rakibtg/pen/xQMwYK – rakibtg Dec 01 '18 at 05:39
  • I think you miss this => https://stackoverflow.com/questions/22707475/how-to-make-a-promise-from-settimeout – Mister Jojo Dec 01 '18 at 05:45
  • Thanks everyone, using a sync loop `for ( const item of messages )` solved the problem :) – rakibtg Dec 01 '18 at 05:47
  • @rakibtg awesome! Will you be posting an answer to your question? – stealththeninja Dec 01 '18 at 05:57
  • 1
    Is this a duplicate of: https://stackoverflow.com/questions/43082934/how-to-execute-promises-sequentially-passing-the-parameters-from-an-array – MattG Dec 01 '18 at 05:59

1 Answers1

1

Promise.all() can be used to pass a list of promises, which all get waited on in parallel.

The code you shared does wait 3 seconds for every iteration, except all those iterations are all happening at the same time.

If you want to not do everything in parallel, but just handle one at a time you can rewrite this to a simple loop:

const app = async () => {
  for (const msg of messages) {
    await wait();
    document.querySelector('#app').innerHTML += msg + ', '
  }
}
Evert
  • 93,428
  • 18
  • 118
  • 189