zwlayer
zwlayer

Reputation: 1824

Understanding asynch behaivor of javascript with an example

I'm completely new in javascript and I'm trying to understand its asynch nature. For this purpose here is my sample code :

  $("#calculate-similarity").click(function(){

        // assume input is an array whose length is larger than 0
        var requestData={"uris":input,"limit":100};
        client=new Ajax(requestData);
        alert('inside .click function');

    })

Ajax=function(requestData){

    alert('inside ajax');
    $.ajax({
        url: 'http://localhost:8080/',
        type:'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(requestData),
        xhrFields: {
            withCredentials: true
        }
    }).done(function(data) {
        $("#ws-results").children().detach();
        $("#ws-results").append('<table id="my-final-table"><thead><th>fname</th><th>furi</th><th>sname</th><th>suri</th><th>similarity</th></thead><tbody></tbody></table>');
        $('#my-final-table').dynatable({
            dataset: {
                records:data
            }
        });      
    });
}

Now, above, I'm creating new Ajax() and inside of it, I'm making a ajax request. As far as I know its asynch event. Therefore, I though that, this request should be completed first of all, and then my other javascript lines (alert('inside .click function')) should be executed. In other words, I would expect :

1) alert inside ajax
2) show my datatable on the browser
3) alert inside .click function

However, I got with the following order :

1) alert inside ajax
2) alert inside .click function
3) show table on the browser

So, what do you suggest me to understand these concepts ? I've a solid background with several programming languages like c++ and java but this is my first time with web development and javascript.

EDIT

If I modify my .click function like below, do you say first of all always 10000 times hello will be printed out and then table will be shown ? Or table would be shown somewhere at the middle of logging ? I mean when the response comes, engine should wait first in order to show it ?

Modified code : (Let's remove all of the alert statements)

$("#calculate-similarity").click(function(){

            // assume input is an array whose length is larger than 0
            var requestData={"uris":input,"limit":100};
            client=new Ajax(requestData);
                for(var z=0;z<10000;z++){
                    console.log(z+'hi!');
                 }

        })

Upvotes: 1

Views: 61

Answers (3)

Quentin
Quentin

Reputation: 944295

As far as I know its asynch event. Therefore, I though that, this request should be completed first of all, and then my other javascript lines should be executed.

That is exactly the opposite of what it means.

The Ajax function will run. It will trigger an HTTP request. The Ajax function will finish. alert will run.

At some point in the future, the HTTP response will arrive and the done event handler will fire.


This is exactly the same principle as:

alert(1);
$("#calculate-similarity").click(function(){ alert(2); });
alert(3);

JavaScript doesn't wait for you to click on calculate-similarity before firing alert(3).


If I modify my .click function like below, do you say first of all always 10000 times hello will be printed out and then table will be shown ? Or table would be shown somewhere at the middle of logging ? I mean when the response comes, engine should wait first in order to show it ?

JavaScript won't interrupt a running function in order to execute a different (event handler) function. It will wait until it isn't busy before it goes looking for events.

Upvotes: 3

dmeglio
dmeglio

Reputation: 2830

I'll try my best to explain it. Think of this more as an analogy, it's not exactly what's going on but I think it might help you understand:

alert('inside ajax'); - this is a blocking call, it will run and wait for you to click OK.

Then when you call Ajax, what you're essentially doing is saying "go make this web request when you have a chance, and when it finishes call my done method." That's a network operation. It could finish in 1 second, it could take many seconds. Rather than freezing up the whole browser, this is done "in the background." So that makes the UI remains responsive. At some point in the future the network request will finish. When it does, the function you specified in done will get called to let you know it finished. Think of making the Ajax request as adding it to a queue rather than actually connecting to the network. When the browser gets to it it will execute your request and wait for the server to respond. When it does, it will signal you to let you know.

Next you alert('inside .click function'); which displays the alert and blocks.

Like I said, that's not a technically accurate description of what's going on, but I'm hoping it helps you understand the principle of it.

Upvotes: 1

Lim H.
Lim H.

Reputation: 10050

  1. new Ajax is object instantiation and it's synchronous. Therefore you get inside ajax as the first result because it happens when your Ajax object is instantiated, not to be confused with when the Ajax request is fired.
  2. alert is executed synchronously, so that's the second thing you get.
  3. $.ajax which wraps around XMLHttpRequest, responsible for firing the actual ajax request, is the only async part in your code and its result, which is encapsulated inside done, is what you get last.

In other words, I think the confusion comes from the fact that you introduce another layer of abstraction called new Ajax() which provide little actual value and a lot of confusion :P. inside ajax signal inside the instantiation of your Ajax object, not the firing of the actual request.

Upvotes: 1

Related Questions