简体   繁体   中英

How to fix: setTimeout function within a forEach function not following correct timeout

I'm trying to make messages show on my site, each after 3 seconds. I'm doing this via an array (containing the messages) with a forEach function to put them in an setTimeout function, but it just show the last message after 3 seconds instead of showing all the messages each after 3 seconds.

I tried debugging, and the weird part here is that IT DOES ACTUALLY WORK IN DEBUG, just not without it.

const travelIntro = $text => {
  const arrMessages = ['You are travelling through empty space...', 'You wake up with only 5% oxygen left barely breathing', 'All of the sudden your ship starts up'];
  arrMessages.forEach(message => {
    setTimeout(function () {
      $text.innerHTML = message;
    }, 3000);
  });
}

So I expect it to switch between each message after 3 seconds, not just showing the last one in the array.

You definitely need to learn about the nature of asynchronism in Javascript

The forEach loop will actually run very fast and for each message it will immediately start a timeout. Each of the timeouts will fire 3000 ms after they have been started. So they all fire after 3000 ms, one after another.

In order for the second one to fire 3000 ms after the first one, which fired after 3000 ms you may want to establish some kind of manual loop

    const arrMessages = ['You are travelling through empty space...', 'You wake up with only 5% oxygen left barely breathing', 'All of the sudden your ship starts up'];

    function doLoop(i) {
       let message = arrMessages[i];
       setTimeout(function () {
          $text.innerHTML = message;
          if(i < arrMessages.length-1)
             doLoop(i+1);
       }, 3000);
    }

    doLoop(0);

I think you are looking for setInterval , then clear it when it returns undefined. Fiddle here: https://jsfiddle.net/xukL1w0a/

const arrMessages = ['You are travelling through empty space...', 'You wake up with only 5% oxygen left barely breathing', 'All of the sudden your ship starts up'];

let messages = setInterval(function () {
  message = arrMessages.shift();
    if (message === undefined) {
     clearInterval(messages);
     return;
  }
  console.log(message)
},3000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM