1

I am wondering how I can solve a hanging page with JS.

I have a JS loop which I'm testing like this, but it seems to hang forever - is there a way to stop it hanging while still completing the script ?:

<div id="my_data"></div>

<script>
function test(value){
output= [];
do{ 
    value++;
    output.push(value);
    document.getElementById('my_data').innerHTML = (output.join(''));
}while(value < 10000000);
alert('end'); // never occurs
}

test(0);
</script>
Reza Mousavi
  • 4,420
  • 5
  • 31
  • 48
Sir
  • 8,135
  • 17
  • 83
  • 146

6 Answers6

7

You're updating the DOM with an increasingly long string ten million times.

If you're some sort of super-being from the future, then maybe this makes sense.

Pointy
  • 405,095
  • 59
  • 585
  • 614
5

Javascript is single-threaded, so nothing else can happen while it's running your loop. It's running ten million times, and on each run it's setting the innerHTML of #my_data to something new. It's very inefficient and seems useless. What are you trying to accomplish?

ziad-saab
  • 19,139
  • 3
  • 36
  • 31
  • I want to see the number increase as it loops – Sir May 30 '12 at 04:14
  • This will not happen. The browser will only re-render after your loop is completed. – ziad-saab May 30 '12 at 04:15
  • There must be a way to do it though. – Sir May 30 '12 at 04:15
  • Yes. If each iteration through the loop uses `setTimeout` to update the DOM, you might see some values popup sometimes. – ziad-saab May 30 '12 at 04:17
  • @Dave: See the demo in my answer. The calculation you're trying to perform is going to override the rendering of the element, so the only solution is to have a timer update your value rapidly. – Blender May 30 '12 at 04:17
4

You are concatenating 10,000,000 consecutive numbers together into a string, which really will not work well on any modern supercomputer.

If you'd like to poll the progress, setup a timer to do it somewhat slower. It isn't practical, but it looks nice: http://jsfiddle.net/V6jjT/2/

HTML:

<div id="my_data"></div>

Script:

var value = 0;
var interval = setInterval(function() {
    if (value > 100) {
        clearInterval(interval);
        return;
    }

    value++;
    document.getElementById('my_data').innerHTML += ' ' + value;
}, 10);
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Blender
  • 289,723
  • 53
  • 439
  • 496
  • Can you update your question mentioning that you want to see the updates as they happen to make the question and answer more helpful to others? – Jason Goemaat May 30 '12 at 06:36
3

Running a tight loop like that will not update anything until it's done; besides, 10M array items?!

If you really want to do this and not let the browser hang until forever you have to use setInterval to allow the browser to refresh in between.

function updater(value, max, interval) {
  var output = [],
  node = document.getElementById('my_data'),
  tid = setInterval(function() {
    if (value++ < max) {
      output.push(value);
      node.innerHTML = (output.join(''));
    } else {
      alert('done');
      clearInterval(tid);
    }
  }, interval);
}

updater(0, 10, 200);
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
1

You should not update the HTML each iteration.

function test(value){
    output= [];
    do { 
        value++;
        output.push(value);
    } while(value < 10000000);
    document.getElementById('my_data').innerHTML = (output.join(''));
    alert('end'); // never occurs
}

should work (although 10 million numbers in a HTML will still need their time to render).

If you want to see numbers running, you should have a look at window.setInterval - the browser needs some time between js execution to refresh its view. So, you will have to rewrite your code running several chunks of data asynchrously. See also:

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • But that will only result in showing the last number i want to see the number increase as it loops. – Sir May 30 '12 at 04:14
  • You can't really. The browser will update its UI to display the numbers when that loop is finished. Before it is hanging cause of the JS execution. – Bergi May 30 '12 at 04:19
0

Tight loop is likely to always exhaust computing power. I would do it in chunks. Say, divide your list into smaller lists and pause 5ms in between lists. I can provide an example if you need.

Junilo
  • 71
  • 5