0

I have this code http://jsfiddle.net/ee1xuaqs/1/ :

function long_running(status_div) { // does something for 2-3 seconds

    var result = 0;
    // Use 1000/700/300 limits in Chrome, 
    //    300/100/100 in IE8, 1000/500/200 in FF
    alert('running');
    for (var i = 0; i < 1000; i++) {
        for (var j = 0; j < 700; j++) {
            for (var k = 0; k < 300; k++) {
                result = result + i + j + k;
            } // end inner
        } // end outer for
    }

}

$('#do_ok').on('click', function () {
    $('#status_ok').text('calculating....');
    window.setTimeout(function (){ long_running('#status_ok') }, 1000);
    $('#status_ok').text('calclation done');
});

Along with this HTML:

<table border=1>
    <tr><td><button id='do_ok'>Do long calc</button></td>
        <td><div id='status_ok'>Not Calculating yet.</div></td>
    </tr>
</table>

Now, when I click on the button, I get 'calculation done' shown up ('Calculating...' probably flashes for a millisecond or two).

As far as I'm aware, each of these 3 commands inside $('#do_ok').on creates a separate event, two for updating the DOM and one for setTimeout which completes after 1 second. For the jQuery DOM update commands, the DOM is updated immediately, however, they also create DOM-repaint events which get processed as usual (this is according to this highly voted SO answer). Since I get 3 events, they should be executed in the appropriate order, first 'Calculating..' updating the screen, then long_running and after all of that, calculation done.

So why do I get 'calculation done' BEFORE long_running is executed?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
daremkd
  • 8,244
  • 6
  • 40
  • 66
  • You've done the closest thing javascript has to "spawning a new thread" with the `setTimeout` line. Someone will come along with better details of the science soon, but there are about 100 duplicates to this question. – Jamiec Jan 20 '16 at 12:28
  • @Jamiec 100 duplicates? Can you point to one? I haven't seen any question that asks as to why render events get priority over timing events. – daremkd Jan 20 '16 at 13:22
  • The number of times ive seen "why does X happen before Y" (where Y is a call to `setTimeout`) is immeasurable. Am I going to go hunting for them now, sadly no! – Jamiec Jan 20 '16 at 13:50

1 Answers1

0

The click callback executes as follows:

  1. $('#status_ok').text is set to 'calculating....'
  2. The setTimeout sets the function you pass as a parameter aside to execute it after the time is out.
  3. $('#status_ok').text is set to 'calculation done'
  4. When a second passes, the function passed to setTimeout gets executed

$('#status_ok').text('calculation done') should be inside the setTimeout function to work properly.

Pedro Paredes
  • 680
  • 8
  • 6
  • This is not the way jQuery functions work. Yes the DOM is updated but an event is dispatched to the renderer in order to show the updated DOM. It's not one operation. – daremkd Jan 20 '16 at 13:21
  • jQuery functions work exactly the same way that any other JS function does. Try this simple example: `(function () { console.log('First'); window.setTimeout(function () { console.log('Second'); }, 1000); console.log('Third'); })();` The output will be `First, Third, Second`. – Pedro Paredes Jan 20 '16 at 16:34