0

So here's the situation:

I have a recursive, asynchronous AJAX call which is pulling data from the server. This recursive call happens only once when the user logs in. I have another page which requires AJAX calls in order to navigate (basically a lazy-loaded tree). While the first AJAX call is happening, these other calls are taking a while to go through, and since the first could make as many as 2,000 requests, this delay can sometimes be fairly long.

Basically what I would like to achieve is to "pause" the recursive call when the other call is made. Pseudo code:

function recursiveAjax(){    
    $.ajax( {
        async : true,
        url : 'someurl',
        dataType : 'json',
        beforeSend : function(xhr) {
            // do stuff
        },
        error : function(xhr, ajaxOptions, thrownError) {
            // handle errors
        },
        success : function(data) {
            //conditions
            recursiveAjax();
        }
    });
}

function navigationAjax(){    
    $.ajax( {
        async : true,
        url : 'someurl',
        dataType : 'json',
        beforeSend : function(xhr) {
            // pause recursiveAjax();
        },
        error : function(xhr, ajaxOptions, thrownError) {
            // handle errors
        },
        success : function(data) {
            //conditions
            // resume recursiveAjax();
        }
    });
}
2
  • That's pretty insane. Try wrapping the recursive calls in timeout blocks, eg on success: setTimeout(function() { recursiveAjax(); }, 500); — that should leave space for the other calls and is a little bit less insane. Commented Jul 5, 2012 at 13:26
  • Take a look at jQuery deferreds Commented Jul 5, 2012 at 13:27

3 Answers 3

2

Simplest way:

window.recurse = true;
function recursiveAjax(){    
    $.ajax( {
        async : true,
        url : 'someurl',
        dataType : 'json',
        beforeSend : function(xhr) {
            // do stuff
        },
        error : function(xhr, ajaxOptions, thrownError) {
            // handle errors
        },
        success : function(data) {
            //conditions
            if(window.recurse){
               recursiveAjax();
            }
        }
    });
}

function navigationAjax(){    
    window.recurse=false;
    $.ajax( {
        async : true,
        url : 'someurl',
        dataType : 'json',
        beforeSend : function(xhr) {
            // pause recursiveAjax();
        },
        error : function(xhr, ajaxOptions, thrownError) {
            // handle errors
        },
        success : function(data) {
            //conditions
            window.recurse=true;
            recursiveAjax();
        }
    });
}
Sign up to request clarification or add additional context in comments.

2 Comments

Good answer but it's making no perceivable difference performance wise. The navigationAjax call is still delayed by a few seconds.
@Squishy: You won't see any performance difference, the only difference is that you are keeping the client code from making another recursive request instead of letting the server queue that requests. However, you are still doing the navigation request while waiting for the response for the recursive requests, so the navigation request will still be queued by the server.
1

As you probably don't want the two requests at the same time, let the recursive method do one or the other. Set a flag when you want the navigation call, and let the recursive method do that request the next iteration:

var navigationCall = false;

function recursiveAjax(){
  if (navigationCall) {
    navigationCall = false;
    $.ajax( {
      async : true,
      url : 'someurl',
      dataType : 'json',
      error : function(xhr, ajaxOptions, thrownError) {
        // handle errors
      },
      success : function(data) {
        //conditions
        recursiveAjax();
      }
    });
  } else {
    $.ajax( {
      async : true,
      url : 'someurl',
      dataType : 'json',
      beforeSend : function(xhr) {
        // do stuff
      },
      error : function(xhr, ajaxOptions, thrownError) {
        // handle errors
      },
      success : function(data) {
        //conditions
        recursiveAjax();
      }
    });
  }
}

function navigationAjax(){
  navigationCall = true;
}

Note: You might want to add a window.TimeOut call to do the recursion to throttle the streams of requests to the server. There is no point in calling the server more often than the human eye can see the changes.

3 Comments

The recursive call is building a data tree in the background - the user will never see it. It would make my life a lot easier if that tree didn't need to exist, but it does, and it needs to be done every time. Thankfully this is all a temporary measure, but it still pains me to see my app performing so poorly.
And that works alright. Still a pretty hefty performance hit but it's about twice as fast as it was before, so at least there's that. Many thanks
Why not limiting the rate at which recursiveAjax(); fires? running it once every 500ms would probably make a huge difference in terms of performance.
1

JavaScript is an asynchronous language and therefore you can do thinks like you want only with callbacks like in the other comment (see above). But think about your problem, most of the time it's better to work asynchronous in the web. Do you really want this?

1 Comment

No, I don't - but my boss does. Like I mentioned, its a temporary measure, so at least this code won't be out in the wild for long.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.