solojuve1897
solojuve1897

Reputation: 165

Ajax-call sync vs async?

I had an issue which I, after several hours of searching, solved when I stumbled upon the fact that one can set the async-option for an ajax-call to false. My code now works exactly as I expect to, but I wonder if my solution is good or if it can be solved in a better way. If my solution is bad, why do you think so? Async vs sync, what is best? Should one always strive to use async-calls as much as possible?

var pageIndex = 0;

(function () {
   GetData();

   $(window).scroll(function () {
       if ($(window).scrollTop() ==
           $(document).height() - $(window).height()) {
           GetData();
       }
   });
})();

$.ajax({
    type: 'GET',
    url: '/Blog/GetPostsByBlogId',
    data: { "id": @Model.First().ReqBlog.Id, "pageindex": pageIndex },
    dataType: 'json',
    success: function (response) {
         DisplayData(response);
    },
    beforeSend: function () {
         $("#progress").show();
    },
    complete: function () {
         $("#progress").hide();
    },
    error: function (response) {
         alert("Error while retrieving data!");
    }
});

In the success I call the following function:

function DisplayData(response)
{
     if (response != null) {
         $.each(response, function (i, post) {
              $.ajax({
                  async: false,
                  url: "/Blog/GetPostPartialView",
                  data: post,
                  type: "POST",
                  success: function (response) {
                       $("#posts-container").append(response);
                  }
               });
            });
            pageIndex++;
      }
}

Without the "async: false" the data is displayed in a random order for every refresh. With the "async: false" the data displays in the correct order, every time.

Edit:

I used the following solution to avoid using async: false.

My DisplayData-function now looks like this:

function DisplayData(response)
{
     if (response != null) {
         $.each(response, function (i, post) {
             $('#posts-container').append($('<div>').load("/Blog/GetPostPartialView", { Id: post.Id, Title: post.Title, Body: post.Body, Created: post.Created, Updated: post.Updated, Views: post.Views, Blog: post.Blog, Tags: post.Tags, Comments: post.Comments, Author: post.Author }));
         });
         pageIndex++;
     }
}

Upvotes: 1

Views: 1109

Answers (2)

ali
ali

Reputation: 1351

async=false attribute will result in blocking execution of javascript code flow which is generally very bad practice. When you use ajax async=true, you cannot be sure the order of multiple ajax calls. If you cannot do anything in server-side, you can collect the retrived data to a data structure in client-side and order as you wish. You can also call upcoming ajax calls on the completion of previous ajax calls. In that way, you get the results in the order you send the ajax requests.

Upvotes: 0

Rory McCrossan
Rory McCrossan

Reputation: 337590

async: false is terrible practice. It is a bad solution, and there are very few cases where it would be valid. It's so bad in fact, that if you check the console you'll see a browser warning telling you not to use it.

With regard to your issue of the order being randomised, it's because the AJAX requests in the loop all complete at different times. To solve this you should remove async: false and either:

  1. Collate the returned data together on the client and then sort() it manually before displaying.

  2. Change your server code so that you pass all data in a single AJAX call, then you can return all the required information in the correct order.

The second option is by far the better solution as it also avoids the DDOS-ing of your server that is currently happening due to your (N blog posts + 1) requests that you're currently flooding it with.

Upvotes: 2

Related Questions