Somchai
Somchai

Reputation: 121

How to update innerHTML in very long running loop javascript

var star = 4125;
var moon = 2946;
var max  = 50;
//-----------------------------------------------------------------------------------

var a,b,c,d,e,f;
var starx,moonx,tokenx;
var token = 0;
var txt;

for (a = max ; a >= 0 ; a--)
{
  for (b = 0 ; b <= max ; b++)
  {
    for (c = 0 ; c <= max ; c++)
    {
      for (d = 0 ; d <= max ; d++)
      {
        for (e = 0 ; e <= max ; e++)
        {
          for (f = 0 ; f <= max ; f++)
          {
            starx  = 75 * (a + b + c + d + e + f);
            moonx  = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
            tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);

            if (starx <= star && moonx <= moon && tokenx >= token)
            {
              token = tokenx;
              txt = tokenx + ',' + starx + ',' + moonx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + '<br>\n';

              document.getElementById("txt").innerHTML += txt;
              console.log(txt);
            }
          }
        }
      }
    }
  }
}

Need help. I am very new to javascript. I would like to run those javascript in android. innerHTML don't update until the loop completed. And can't see console log in android too.

Upvotes: 0

Views: 397

Answers (3)

Somchai
Somchai

Reputation: 121

Web workers can do long running task.

See here: https://www.w3schools.com/html/html5_webworkers.asp

Notes:

Chrome doesn't support web workers when load script from local. You have to add option Chrome.exe --allow-file-access-from-files

Firefox allow local file.

<!DOCTYPE html>

<html>
<body>
<button onclick="startWorker()">Start Worker</button>
<button onclick="stopWorker()">Stop Worker</button><br><br>
<pre id="txt">
Hello
</pre>
<script>

var w;

function startWorker()
{
    if(typeof(Worker) !== "undefined") 
    {
            if(typeof(w) == "undefined") 
        {
            w = new Worker("StarForge.js");
        }

        w.onmessage = function(event)
        {
            document.getElementById("txt").innerHTML += event.data;
        };
    }
    else 
    {
        document.getElementById("txt").innerHTML = "Sorry! No Web Worker support.";
    }
}


function stopWorker()
{ 
    w.terminate();
    w = undefined;
}


</script>
</body>
</html>

And in the StarForge.js

function gen()
{

var moon = 2946;
var star = 4125;
var max  = 50;


var a,b,c,d,e,f;
var moonx,starx,tokenx;
var token = 0;
var txt;


for (a = 0 ; a <= max ; a++)
{
    for (b = 0 ; b <= max ; b++)
    {
        for (c = 0 ; c <= max ; c++)
        {
            for (d = 0 ; d <= max ; d++)
            {
                for (e = 0 ; e <= max ; e++)
                {
                    for (f = 0 ; f <= max ; f++)
                    {
                        tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);
                        moonx  = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
                        starx  = 75 * (a + b + c + d + e + f);

                        if (tokenx >= token && moonx <= moon && starx <= star)
                        {
                            token = tokenx;
                            txt = tokenx + ',' + moonx + ',' + starx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f;
                            postMessage(txt)
                            console.log(txt);
                        }
                    }
                }
            }
        }
    }
}


postMessage("--- End ---");
console.log("--- End ---");


}


gen();

Upvotes: 0

Calvin
Calvin

Reputation: 149

Use generator function* to yield text. DOM element innerHTML could be updated via setInterval timer.

function* cal() {
var star = 4125;
var moon = 2946;
var max = 50; 
var a, b, c, d, e, f;
var starx, moonx, tokenx;
var token = 0;
var txt;
for (a = max; a >= 0; a--) {
    for (b = 0; b <= max; b++) {
        for (c = 0; c <= max; c++) {
            for (d = 0; d <= max; d++) {
                for (e = 0; e <= max; e++) {
                    for (f = 0; f <= max; f++) {
                        starx = 75 * (a + b + c + d + e + f);
                        moonx = (10 * a) + (30 * b) + (50 * c) + (75 * d) + (125 * e) + (200 * f);
                        tokenx = (210 * a) + (235 * b) + (260 * c) + (300 * d) + (375 * e) + (500 * f);
                        if (starx <= star && moonx <= moon && tokenx >= token) {
                            token = tokenx;
                            txt = tokenx + ',' + starx + ',' + moonx + ',' + a + ',' + b + ',' + c + ',' + d + ',' + e + ',' + f + '<br>\n';
                            // document.getElementById("txt").innerHTML += txt;
                            console.log(txt);
                            yield txt;
                        }
                    }
                }
            }
        }
    }
}


}

function run() {
    gen = cal();
    setInterval(()=> document.getElementById("txt").innerHTML += 
gen.next().value, 10);
}

run();

Upvotes: 1

Nick Parsons
Nick Parsons

Reputation: 50884

If you want to show the output of the loop at each iteration you can use setInterval() like so:

for(let a = 0; a < 10; a++) {
  document.body.innerHTML += "Hello world!" +a +"<br />";
}

document.body.innerHTML += "<br /> Loop but shows output at each iteration: <br />";
let a = 0;
let aLoop = setInterval(function() {
  if(a < 10) {
    document.body.innerHTML += "Hello world!" +a +"<br />";
    a++;
  } else {
    clearInterval(iLoop);
  }
}, 100);

However, this would require you to convert a lot of your code and would get messy. If all you wish to do is see the output on android you can try alert(txt); to see the output instead.

Upvotes: 1

Related Questions