0

I understand that JavaScript is single threaded (as explained in this question: If Javascript is not multithreaded, is there any reason to implement asynchronous Ajax Queuing?), however I am trying to understand how this applies to the application I have developed. Please see the code below:

function GetSQLTable() {
        var str = $("#<%=fieldDatabaseReferences.ClientID%>")[0].value
        var res = str.split(",");
        $("#LoadingImage").show();
        $("#LoadingImage2").show();

        for (var i = 0; i < res.length; i++) {
            (function (i, res) {
                setTimeout(function () {
                    GetSQLTable2(i, res.length, res)
                }, 0);
            })(i, res);
        }
    }

function GetSQLTable2(i,reslength,res) {
            //if (i == 0)
            //{
            //    var start = new Date().getTime();
            //}
        var div = document.createElement('div');
            div.id = "div" + i
            document.getElementById('info_div').appendChild(div);

            var PossiblesPage = false;
            $.ajax({
                type: "POST",
                url: "PrimaryNominalAjax.aspx/GetSQLTable",
                data: '{username: "' + $("#<%=fieldUserName.ClientID%>")[0].value + '", terminalname: "' + $("#<%=fieldTerminalName.ClientID%>")[0].value + '", terminalip: "' + $("#<%=fieldTerminalIP.ClientID%>")[0].value + '", mappingid: "' + res[i] + '", usergroup: "' + $("#<%=fieldUserGroup.ClientID%>")[0].value + '", usn: "' + $("#<%=fieldUSN.ClientID%>")[0].value + '", requester: "' + $("#<%=fieldRequester.ClientID%>")[0].value + '", reason: "' + $("#<%=fieldReason.ClientID%>")[0].value + '", rrd: "' + $("#<%=fieldRRD.ClientID%>")[0].value + '", review: "' + $("#<%=fieldReview.ClientID%>")[0].value + '", possibles: "' + PossiblesPage + '",linkno: "", urn1: "", urn2: ""}',
                contentType: "application/json; charset=utf-8",
                timeout: 80000000,
                dataType: "json",
                success: OnSuccess(i, reslength),
                error: OnError,
                failure: function (response) {
                    alert('there was an error loading the webpage')
                }
            });
        }

fieldDatabaseReferences is populated on the server side. The AJAX connects to multiple local databases (up to 30) and puts the information on the screen as and when it is ready.

The calls to the various database servers are asynchronous. Surely this has a multi threaded effect?

Community
  • 1
  • 1
w0051977
  • 15,099
  • 32
  • 152
  • 329
  • What is your question again? – Salman A Dec 16 '14 at 12:14
  • 2
    Nope. Multithreading is different than asynchronous. Sure, the requests are happening in theory *simultaneously* but Javascript works on one single threaded event loop, so all of `OnSuccess` is executed in one go. Unlike multithreading, where each atomic statement inside `OnSuccess` could be executed in an arbitrary fashion – CodingIntrigue Dec 16 '14 at 12:15
  • BTW: this line `success: OnSuccess(i, reslength),` (probably) doesnt do what you think it does. – Jamiec Dec 16 '14 at 12:27
  • @RGraham, thanks. What do you mean by "one go". I assumed that the 'On Success' events were run synchronously as this is JavaScript code? – w0051977 Dec 16 '14 at 12:27
  • @Jamiec, I know that I=10 could arrive in the OnSuccess before I=1. Is that what you mean? – w0051977 Dec 16 '14 at 12:29
  • No, you're assigning the *result* of your `OnScuccess` method to the callback (having executed it immediately) - I assume you want the `OnSuccess` Method to only execute when your ajax request completes! – Jamiec Dec 16 '14 at 12:30
  • @Jamiec, it is an incremental page load. Information appears as and when it is ready. Therefore OnSuccess runs many times. Does that make sense. – w0051977 Dec 16 '14 at 13:33

1 Answers1

1

JavaScript is single threaded. When asynchronous events occur, they are are pushed into a queue waiting to be executed until the thread is idle. Consider the following example:

var run = true;
var brk = Date.now() + 5000;    // five seconds from now
setTimeout(function(){
    run = false;                // set the run variable to false _asynchronously_
}, 1000);                       // after one second
while(run && Date.now() < brk); // loop while both conditions are true
console.log("run:", run);       // logs run: true (which was the initial value)

When do you suppose the loop will terminate? One second? No it would run indefinitely (if Date.now check was not there). The fact that the value logged in console is true confirms that the timeout is not fired. It is in the queue, waiting for the var run = true...console.log() block to terminate.


As for your example, the order of execution would be:

/* note: no two functions execute at same time */
GetSQLTable();
/* functions scheduled via setTimeout execute one by one */
GetSQLTable2(0, ...);
GetSQLTable2(1, ...);
GetSQLTable2(2, ...);
/* AJAX requests complete one by one, not necessarily in the order they started */
OnSuccess(2);
OnSuccess(0);
/* JavaScript thread could be idle during callbacks */
OnSuccess(1);

References:

Salman A
  • 262,204
  • 82
  • 430
  • 521