17

I'm running two ajax calls on page load. They both work as expected if I open the page in desktop browser.

However, if I open the same page in an android browser (Chrome for example), I noticed that the second ajax function's response is waiting for completion of the first ajax function which kinda defeats the purpose of asynchronous-ness. Both are executing concurrently, but the second function's success is only executing after completion of first ajax call's success function.

Screenshot

Ajax Calls

The fact that it is working in desktop browsers and not in android browsers leads me to believe that there must be some kind of setting in android which is blocking concurrent asynchronous calls.

If that is the case, is it possible that I can disable that? My code is as follows btw:

$(function(){           
       var intervalID = window.setInterval(function(){
                doAjax(); // this is the function which is waiting for completion of first ajax call
            }, 2000);

      // the first ajax call
      $.ajax({
    type:'post',
    url:'progress-insert.php', // basically is meant for insertion of records into db
    success:function(data)
    {
       clearInterval(intervalID);
    }   
     });
     
     function doAjax()
     {          
    $.ajax({
        type:'post',
        url:'progress-update.php', // basically returns how many records have been inserted so far
        success:function(data)
        {
                // do something
        }
    }); 
      }
     
});
Community
  • 1
  • 1
asprin
  • 9,579
  • 12
  • 66
  • 119
  • Are you sure this isn't running into a limit on how many async connections your mobile browser is attempting to do at the same time? – Mark Dec 13 '13 at 13:46
  • And is there is way to find out if that is really the case? – asprin Dec 13 '13 at 13:47
  • 2
    "the second ajax function is waiting for completion of the first ajax function" Do you mean that the first ajax call lasts more than 2 seconds ? If not, the second call can only starts at the end of the first one, right ? Because of the clearInterval. – TCHdvlp Dec 13 '13 at 13:58
  • @TCHdvlp The first ajax calls runs for roughly 14-16 seconds (inserting rows into db). In the meantime, I run the second the ajax function to see how many records have been inserted so far and display that on the screen. Both functions run simultaneously on desktop browsers, so I guess it's not compulsory that the second function should run only after the completion of the first function. – asprin Dec 13 '13 at 14:11
  • You're probably hitting the ajax request limit. IIRC for desktop browsers it's generally 2 (with images/css/js/etc filling up the remaining ~6 slots to a domain). When this happens, the ajax request is just silently queued up in the browser until there's an open slot, but is treated by the JS as if it is already running (hence that output in the console). _If_ this is the problem, it's a browser limitation you can't overcome unless you retrieve the data in a different way. – Izkata Dec 20 '13 at 19:06
  • In the meantime, you can fix your code so it doesn't stack up requests: Don't use `setInterval`, instead call `setTimeout` from within the `complete` callback in `doAjax` (but only if not yet complete), then call `doAjax` once to start the iterations. – Izkata Dec 20 '13 at 19:09
  • What happens when you prime-the-pump by calling `doAjax()` before your progress-insert.php ajax call? – tjklemz Dec 23 '13 at 02:38
  • Try with **async: true** – Chandresh M Dec 23 '13 at 05:01
  • @tjklemz Tried that too and the process is reversed in this case – asprin Dec 23 '13 at 07:17
  • @Chandresh Tried that too but didn't work either – asprin Dec 23 '13 at 07:18
  • @TCHdvlp I have the same doubt, if the first request isn't last for 2 sec, the setInterval will be canceled if the first one success, right? – Daiwei Dec 23 '13 at 07:19
  • Try case A or B, adobe..in my answer.. and check jquery version..Greetings @Chandresh also is a good answer, ajax receive like parameter async: true, solve the ajaxsetup previusly seted.. – Sk. Dec 23 '13 at 21:43

4 Answers4

2

Check out this SO question

There's an answer that points to Browserscope that will give you some info on how many simultaneous connections can be made in modern browsers. One idea to test if you're hitting some kind of limit would be to try to host the two endpoints on separate domains. If it works then you'll know that the browsers has a limit of 1 call per domain, although from the Browserscope list it looks as though that shouldn't be the case.

I also ran your code locally and did not see the same behaviour that you're describing (using Xcode iPhone simulator iOS7 and mobile Safari).

Also, you seem to have two $(function(){ setups, one wrapped in the other. Maybe fix that up and see if it makes a difference...

Community
  • 1
  • 1
koosa
  • 2,966
  • 3
  • 31
  • 46
  • I think the code would work on simulators. Also, I do not see two `$(functions(){` functions in the code I posted above...or maybe I'm not able to spot it – asprin Dec 19 '13 at 07:29
2

Unfortunately all browsers implementation of javascript is single-threaded, which means async calls are async for servers but not for same javascript & thus wait for old request. What you can do to overcome that is to push requests in a variable & next time check if request status is not 200 Ok / Success, don't make any further call for same function, sample code can be like:

requests.push($.ajax({
        type:'post',
        url:'progress-update.php', // basically returns how many records have been inserted so far
        success:function(data)
        {
              for(var i = 0; i < requests.length; i++)
              requests[i].abort();
        }
    })); 
Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
2

This complete approach maybe help you

CASE A ...one ajax at time

<script type="text/javascript" >
//Global Variable
$.numx={loaded:false, timerx:0 }


// Document Ready
jQuery(function ($) {

    // button click to insert
    $("#button_click").on("click", function(){
         //Ajax call Insert...myabe help you the insert returns some in json
         $.getJSON( 'progress-insert.php', function(json) { 
              //the waiting function for insert is ready 
              $.numx.timerx=setInterval("waiting_insert()",50);
              if(json!=null){
                   // set to the global variable the insert is ready..and pass to continue 
                   $.numx.loaded=true;
                   // paste another actions to perform... 
               }
          });

    });

});



function waiting_insert(){
    if( $.numx.loaded==true){ 
                // tell to the waiting no more waiting
        clearInterval($.numx.timerx);
              // HERE perform the second ajax progress_update.php
        }
}
</script>

CASE B - MANY AJAX AT TIME Basically remove the setinterval and clearInterval and execute has many ajax call as you want in the same function... like this

<script type="text/javascript" >
// window load .. is charged in event load of page
$(window).load(function(){

     // two ajax calls at the same time

     $.ajax({
    type:'post',
    url:'progress-insert.php',
    success:function(data)
    {
       //do something
    }  
   });


    $.ajax({
        type:'post',
        url:'progress-update.php', // basically returns how many records have been inserted so far
        success:function(data)
        {
                // do something
        }
   });
});
</script>

Adicionally check your version of Jquery As of jQuery 1.8, the use of async: false is deprecated in previous version async false, maybe has been seted in global like part of $.ajaxSetup() making calls sync ...

Sk.
  • 460
  • 7
  • 15
0

I think this is because of writing sessions in your php files.

use

session_write_close()

after writitng to $_SESSION

hope help you.

Arash Younesi
  • 1,671
  • 1
  • 14
  • 23