6

I am making an ajax call to the server. The code I need to run can be divided into 3 groups.

  1. Code that needs to run before the ajax call ins made (preparing the json object going to the server)
  2. Code that needs to be run after the ajax call has returned (uses what was sent back from the server)
  3. Code that needs to be run between the time the user presses a button and the time everything is done. This code does not need the returned json object.

It would be ideal to run the code in group 3 after making the ajax call and before the results are back to gain the best user experience and performance.

Can this be done?

How?

1
  • 1
    did you try reading the docs?? There are explanations for all of your cases api.jquery.com/jQuery.ajax Commented Nov 17, 2012 at 1:24

2 Answers 2

11

Very simply:

function someFunction() {
    //1. code that needs to run before ajax
    $.ajax({...}).done(function () {
        //2. code that needs to be run after the ajax call has returned
    });
    //3. code that needs to be run between the time the user presses
    //   a button and the time everything is done.
}

This works because JavaScript is synchronous in execution (unless workers are being used, but that's unrelated to this particular issue). The first bit of code will run, then the ajax call will tell the browser to start an XHR request, but someFunction hasn't finished, so it will continue to execute synchronously.

Once someFunction is done, the control flow will be opened up to any asynchronous events that occur, eventually leading to the done callback.

To be fair, asynchronous event-oriented programming is not easy for most people to wrap their heads around. It's easy to lose track of what code is supposed to occur at what time.

Here's an easily executable example of how asynchronous behavior works:

(function () {
    alert(1);
    setTimeout(function () {
        alert(2);
    }, 0); //note the 0ms delay
    alert(3);
}());

The order of alerts will be 1, 3, 2. setTimeout will not call its callback synchronously as it relies on waiting for the specified amount of time to elapse, so even if no time is supposed to elapse, it still has to wait for the current function to finish before it can continue.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 - This is something that many developers have trouble grasping.
Is //3 really guaranteed to run before //2? Say //3 contains a lot of functions that take a long time to compute/complete, couldn't //2 theoretically jump into the call stack at any point during the execution of whatever's in //3? I don't mean asynchrous calls, I'm just thinking that since //2 is event driven the event might possibly fire at any given point in the execution.
@Jan, the "firing" of an async event is simply adding a function call to the execution flow queue. The queue moves on to the next function call only once the previously queued functions have completely finished execution. It is not possible to intermingle function calls unless they explicitly use multi-threading such as with workers.
0

Executing an ajax call when reacting to a client event or in any other scenario allows you to specify code in callbacks as well as code that executes immediately after the ajax code is made (not in the callback).

Example:

// Code before the ajax call is made
$.ajax({
    params, //other key values such as data
    success: function (data) {
       // one of the possible callbacks
    }
});
// Code executed immediately after ajax call is performed
// This is executed before or after the callback is complete
// In most cases it's before

So anything executed before the ajax call is made is guaranteed to execute before. Anything immediately after the ajax call is almost guaranteed to execute before the callback is called. The callback is guaranteed to execute after the server returns a response.

4 Comments

"This is executed before or after the callback is complete", I was going to downvote this, as callbacks can't happen before its complete, but then I remembered it's possible to have a synchronous callback if it's used as an option. I'm not sure I like how you've worded it, as it implies that an async callback could happen before the control flow was released, which it will not.
@zzzzBov You can also have an async code after the async code. So it's not guaranteed to execute before the first callback. This is the reason why my answer is such. Feel free to edit if you think you can improve my answer :)
the calling of the async code (such as setTimeout(fn, delay)) will execute before any asynchronous callback can occur. After the function has executed, any queued functions will be executed in the order in which they were called. For example, It's possible that the success callback will use cached data, and queue its callback immediately, it will still be guaranteed to occur after the currently executing function has finished.
@zzzzBov Agreed. Still js is syncronous so there is cases where callback executes before the code after, so I gotta be accurate by saying "before or after" otherwise I would be wrong :)

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.