1

I written the following code that displays each item of an array using a random timer delay.

const letters = ['H', 'e', 'l', 'l','o'];
const typeLetters = _ => {
    letters.forEach((letter) => {
        let ranNum = Math.ceil(Math.random() * 1000);
        setTimeout(function(ranNum) {
            lettersCon.textContent += letter;
        }, ranNum * 1);
    })
}

The problem I've got is the array items aren't being displayed in order, should display Hello. I believe this is due to how the eventloop works.

How can I use a random timer delay whilst keeping the output in order.

  • 3
    The letters do not show up in order *because* of the random delay. Whichever letter gets the shortest delay will be first, etc. – Pointy Dec 31 '18 at 14:26
  • You need to use a recursive function instead of a loop. The loops sets all the timeouts at once, the recursive function should call the timeout for each letter only after the previous timeout finished. – arieljuod Dec 31 '18 at 14:28
  • Note that `ranNum * 1` serves no purpose in the above (at the end of the `setTimeout` call). – T.J. Crowder Dec 31 '18 at 14:28
  • 1
    @arieljuod - Well, it doesn't *have* to be recursive. It could keep track of previous random timeouts and add them to the current one, requiring only minimal changes to the OP's code: Outside the `forEach`: `let total = 0;` then in the `setTimeout` call, use `total + ranNum`, then after the `setTimeout` call, `total += ranNum;`. – T.J. Crowder Dec 31 '18 at 14:29
  • maybe you have a look to this thread: https://stackoverflow.com/q/32081949/1447675 – Nina Scholz Dec 31 '18 at 16:13

1 Answers1

1

What about something like this?

const letters = ['H', 'e', 'l', 'l','o'];
const typeLetters = _ => {
    let total= 0;
    letters.forEach((letter) => {
        let ranNum = Math.ceil(Math.random() * 1000);
        total+=ranNum;
        setTimeout(function(ranNum) {
            lettersCon.textContent += letter;
        }, total);
    })
}
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90