3

I am experiencing two issues with my jQuery record-inserting process, and I am hoping that this wonderful SO community can help me to solve at least one of those issues. These are the issues:

Issue 1 - Intermittent server delay

The first issue relates to the fact that my Ubuntu 10.04 server seems to exhibit intermittent, 4.5 second delays when doing a POST of data to the mySQL database. Most POST commands are executed within a normal amount of milliseconds, but when a delay occurs, it always seems to be for approximately 4.5 seconds. This is not a busy, public server so it shouldn't be a matter of server load being the problem. These short videos demonstrate what I am trying to explain:

Video 1 Video 2

I have posted a question on serverfault and am awaiting some input from that forum which is probably more appropriate for this Issue 1.

Issue 2 - Timing of jQuery POST and GET Methods

The real issue that I am trying to resolve is to prevent the call to GET before all of the calls to POST have completed. Currently, I have implemented $.when.apply to delay the sending of GET. Here is the code for that:

function(){
  $.when.apply(undefined, InsertTheAPPs()).done(function (){
    $.ajax({
      url: sURL + "fileappeal/send_apps_email",
      success: function() {
        var m = $.msg("my message",
        {header:'my header', live:10000});
        setTimeout(function(){
          if(m)m.setBody('...my other message.');
        },3000);
        setTimeout(function(){
          if(m)m.close(function(){
              window.location.replace(sURL+'client/view');
          });
        },6000);
        $('#ajaxShield').fadeOut(1000);
      },
      error: function(){
          $.msg("error message",
          {header:'error header', live:10000});
      }
    });
  });
}

My problem arises due to the delay described above in Issue 1. The GET method is being called after all of the POST methods have begun, but I need the GET method to wait until all of the POST methods have ended. This is the issue that I need assistance with. Basically, what is happening is happening wrong here is that my confirmation email is being sent before all of the records have been completely inserted into the mySQL database.

Here is the code for the jQuery $.each loop. This is the code that needs to not only begin, but must end before the ajax call to fileappeal/send_apps_email above:

function InsertTheAPPs(){
  $('input[name=c_maybe].c_box').each(function(){
    var jqxhrs = [];
    if($(this).prop('checked')){
      var rn = $(this).prop('value');
      jqxhrs.push(
        $.ajax({
          url: sURL + 'fileappeal/insert_app',
          type:"POST",
          dataType: 'text',
          data: {'rn': rn},
          error: function(data) {console.log('Error:'+rn+'_'+data);}
        })
      )
    return jqxhrs;
    }
  });
}

Anyone have any suggestions for how I can workaround the server delay issue and prevent the call to the GET before all of the POST methods have completed? Thanks.

Community
  • 1
  • 1
DanielAttard
  • 3,467
  • 9
  • 55
  • 104
  • you're dealing with asynchronous code. using time delays is **NOT** an appropriate way of keeping things sequential. use a 3 second delay in your code, and you'll end up with a 3.1 second delay on the server. **boom** out-of-sequence execution. **CHAIN** your requests. fire off a post, have its success handler fire off the next post, etc... and then when all the posts are done, the final post's success handler fires off the get. ... or just witch to synchronous ajax instead. – Marc B Jan 30 '13 at 14:44
  • Thanks Marc. I am not _using_ a time delay, but _experiencing_ a time delay. I don't know why the 4.5 second delay is happening on the server. I like your idea of chaining the requests one after the other and then having the final post's success handler fire off the GET. This makes sense, but I don't have any idea how to implement it. You also suggested switching to synchronous ajax instead. How would I do that? Thanks. – DanielAttard Jan 30 '13 at 15:22

1 Answers1

1

There's a small problem with your post. After you resolve it, this post should help you finish out your code: jQuery Deferred - waiting for multiple AJAX requests to finish

You're returning inside the .each but the function itself doesn't return anything. So your delay is not being given the array of ajax calls to wait for. And also, since your jqhrs is defined inside the each, the scope is per iteration over each c_box. Your method should look like this:

function InsertTheAPPs(){
    var jqxhrs = [];

    $('input[name=c_maybe].c_box').each(function(){         
        if($(this).prop('checked')){ 
            var rn = $(this).prop('value'); 
            jqxhrs.push(
                $.ajax({
                    url: sURL + 'fileappeal/insert_app',
                    type:"POST",
                    dataType: 'text',
                    data: {'rn': rn},
                    error: function(data) {console.log('Error:'+rn+'_'+data);}
                })
            )
        }
    });

    return jqxhrs;
} 

You can also make your code easier. Since you just want to know if something is checked you can use the jquery pseudo class filter :checked such as:

function InsertTheAPPs(){
    var jqxhrs = [];

    $('input[name=c_maybe].c_box').filter(':checked').each(function(){         
        var rn = $(this).prop('value'); 
        jqxhrs.push(
            $.ajax({
                url: sURL + 'fileappeal/insert_app',
                type:"POST",
                dataType: 'text',
                data: {'rn': rn},
                error: function(data) {console.log('Error:'+rn+'_'+data);}
            })
        )
    });

    return jqxhrs;
} 

You could combine the filter on :checked into the main filter such as $('input[name=c_maybe].c_box:checked') but I left it in long form to really demonstrate what was going on.

Community
  • 1
  • 1
Eli Gassert
  • 9,745
  • 3
  • 30
  • 39
  • Thanks for this Eli. I am going to give it a shot now and will let you know how I make out. – DanielAttard Jan 30 '13 at 15:23
  • Hi Eli, thanks for the comment. You've mentioned that there is a small problem with my and referred me to a good question on SO, but I don't know what the error is you are referring to. Is your revised function supposed to be the fix to the problem? I have implemented it, but I am still getting the same problem. The GET is firing before the POSTs have completed. – DanielAttard Jan 30 '13 at 16:25
  • The problem I referred to was fixed in my post -- it was the fact that you weren't returning the array properly. The SO article was just to show it being used. Can you post your code up to jsfiddle? For reference, here's another SO doing almost exactly what you want http://stackoverflow.com/questions/4878887/how-do-you-work-with-an-array-of-jquery-deferreds so it should be pretty straight forward. – Eli Gassert Jan 30 '13 at 16:49