Home > Net >  Javascript: Run function again only after it has been completed
Javascript: Run function again only after it has been completed

Time:10-30

So I'm trying to make a program that adds text to a web-page, like so:

Hello
Morning
Morning
Morning
Morning
Evening

There should be:

  1. 5 second delay between "Hello" and the first "Morning".
  2. 5 second delay between each "Morning".
  3. 6 second delay between the last "Morning" and "Evening".

Here's the whole HTML and JavaScript I've got so far.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Test</title>
</head>
<body>
  <div>
    <ul id="notifications" style="list-style-type:none;margin-left:10%;">

    </ul>
  </div>

<script>
function notify(msg, loops, taskTime) {
    var ul = document.getElementById("notifications");
    for (let i = 0; i < loops; i  ) {
        (function(i) {
          window.setTimeout(function() {
            var li = document.createElement("li")
            li.appendChild(document.createTextNode(`${msg}`));
            ul.appendChild(li)
          }, taskTime * i)
        }(i))
    }
}

notify('Hello', 1, 5000)
notify('Morning', 4, 5000)
notify('Evening', 1, 6000)
</script>
</body>
</html>

My problem is that on loading the web-page, the output is:

Hello
Morning
Evening
Morning
Morning
Morning

How can I make sure that the function is ran in the order I want it to and not this mixed output? The first 3 outputs also appear instantly instead of a delay. How do I avoid that?

CodePudding user response:

Multiply the number of miliseconds so the setTimeout that comes after has the correct time assigned. Also, you was multiplying the taskTime and i, which was always 0. I replaced i with i 1 instead.

Just try this JavaScript code instead (it works):

function notify(msg, loops, taskTime) {
  var ul = document.getElementById("notifications");
  for (let i = 0; i < loops; i  ) {
    (function (i) {
      window.setTimeout(function () {
        var li = document.createElement("li")
        li.appendChild(document.createTextNode(`${msg}`));
        ul.appendChild(li)
      }, taskTime * (i   1))
    }(i))
  }
}

notify('Hello', 1, 5000)
notify('Morning', 4, 5000 * 2)
notify('Evening', 1, 6000   5000 * 6)

CodePudding user response:

tasks = [
    {message: 'Hello', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Morning', delay: 5000},
    {message: 'Evening', delay: 6000},
]

function runTask(index) {
    var ul = document.getElementById("notifications");
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(`${tasks[index].message}`));
    ul.appendChild(li);
    if(index < tasks.length - 1){
        setTimeout( () => runTask(index   1), tasks[index].delay);
    }
}

if(tasks.length > 0) runTask(0); //make sure the task list has at least one element.
  • Related