3

In short, how do I let alert(1) run first:

    $.post('example.php', function() {
        alert(1);
    })
    alert(2);
    alert(3);
    alert(4);

But jquery ajax call seem like run in asynchronous method. So JavaScript will run everything below first, alert(2) to alert(4), then back to the post method, alert(1).

Certainly I can just put the code in the ajax function, but this make no sense when I have dozens of functions, then I would have to add the code to all functions.

    $.post('example.php', function() {
        alert(1);
        example();
    })

    function example() {
        alert(2);
        alert(3);
        alert(4);
    }

I want to get some json data from an ajax call, and use it later. So is there any smart solution?


2021-08-25

after 8 years, introduction of async / await is awesome, i don't really use jquery anymore, so i didn't test the code

await Promise.resolve($.post('example.php', function() {
    alert(1);
    example();
}));

alert(2);
alert(3);
alert(4);
aptx
  • 73
  • 1
  • 6
  • 2
    Am I missing something? Simply put `alert(1)` outside of your callback function, like all of the others. – Brad May 18 '13 at 23:27
  • 3
    The second way you show is the normal way to do it - you can pass the returned data to `example()`. @Brad - obviously the OP has simplified the code, where the real code is setting a value or something (the question does mention getting data from the Ajax call and using it later). – nnnnnn May 18 '13 at 23:28
  • I think you may be looking for this very common question http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – elclanrs May 18 '13 at 23:28
  • You could set the syncronous flag I think if you want to wait for the response before continuing – NickSlash May 18 '13 at 23:31
  • Do you have tried http://api.jquery.com/jQuery.when/ I am sure this will solve your puzzle. – Anirudha Gupta May 18 '13 at 23:41
  • @Brad because the `alert(1)` is base on the result of the ajax call, @nnnnnn yes, this will be the way if I only have one ajax call, @elclanrs @F1beta I figure out the `$.when().then()` method works out for me, thx for the help – aptx May 19 '13 at 22:50
  • @F1beta can you make a reply so I can accept your as the answer – aptx May 19 '13 at 23:05
  • @aptx I have posted the answer on this thread. – Anirudha Gupta May 20 '13 at 04:01
  • @aptx Do you got it :) – Anirudha Gupta May 22 '13 at 04:24

4 Answers4

2

"Certainly I can just put the code in the ajax function, but this make no sense when I have dozens of functions, then I would have to add the code to all functions."

There are many patters that can make this easier, but if you're saying that dozens of functions may need to call this post, you could just put the post in a function, and have the function receive a callback.

function myPost(callback) {
    $.post('example.php', function(data) {
        alert(1);
        callback(data);
    })
}


// These are your "dozens of functions"
function a2() { alert(2); }
function a3() { alert(3); }
function a4() { alert(4); }


// These would be at various places in your application
myPost(a1);
myPost(a2);
myPost(a3);

Ultimately the best approach depends on what you mean by "dozens of functions", but certainly you won't need to do the hard coding that you seem to imply.

Passing functions as arguments is often the way to go, but there are other patterns as well that will set up a queue if that's what's needed.

  • 1
    What do you thing for http://api.jquery.com/jQuery.when/ I thing $.when or $.then can make this work :) – Anirudha Gupta May 18 '13 at 23:41
  • I apologize I should have clarified that I have a dozens of ajax functions need a universal callback function. – aptx May 19 '13 at 22:44
2

in jQuery I simply prefer to use $.when and $.then it's easy to do and code is more readable using this.

function CatchTheFish(){
console.log('we are catching the fish');
}
function EattheFish(){
console.log('now time to eat this fish');
}
$.when ( CatchTheFish() ).then( EattheFish() );

This code is work in latest version of jQuery 1.9.1

Anirudha Gupta
  • 9,073
  • 9
  • 54
  • 79
0

The reason the alerts are firing in that order is because the "A" in AJAX stands for Asynchronous.

Here is how the code executes:

  • The post method sends a request to the server, the second parameter is a callback function which will be called later once the request is returned by the server.
  • It then proceeds to the next line of code after the post call, firing alert(2);
  • Then the next line firing alert(3);
  • Then the next line firing alert(4);
  • This block of code is done running so control returns to the event loop
  • Once the server returns the Ajax request, the callback function is called firing alert(1)

The best way to solve this would probably be to just move all of the code inside of the callback, that way it will only run once the request has been returned.

$.post('example.php', function() {
    alert(1);
    alert(2);
    alert(3);
    alert(4);
})

There probably isn't a need to put it in another function and call it as you suggested at the end of your question.

I would avoid "synchronous" Ajax requests, aside from being an oxymoron, they run counter to the whole purpose of using Ajax. Using Ajax should make your application more responsive, using synchronous requests does the opposite, it can cause the browser to lock up if a request timesout or takes a longtime to return from the server.

Useless Code
  • 12,123
  • 5
  • 35
  • 40
  • I do understand why its happening, but I do want to put in it the single callback function, because if I have 12 `$.post()` then I would have to hard code it 12 times – aptx May 19 '13 at 22:57
  • @aptx Ah, then just put all of the calls that they have in common in a function and call it in each of your callbacks like you suggested at the end of the question. – Useless Code May 19 '13 at 23:17
  • I used a variable to call a series of ajax function depend on user input, like `example[variable]()` to call `example['search']()` or `example['login']()`, each of them have random ajax functions to do the work, by using `$.when().then()` I am able to only code it once, but If I put it in the callback function I would still have to hardcode it `example_callback()` 12 times, do you see the difference – aptx May 23 '13 at 00:54
0

Here's an alternative that makes use of jQuery's custom events. It's basically like the other non-synchronous-suggesting answers, just looks slightly different and may help you keep our code nice and clean...

Use an object to bind a custom event to. Bind one or more handlers using the on method of jQuery on that object. Trigger the custom event at the end of your asynchronous function and jQuery will do the rest for you.

Example:

(function($){
    var fakeAsync = {};
    function fakeAsyncFunction( ) {
        alert(1);
        $(fakeAsync).trigger('customDone');
    }

    function a( ) {
        alert(2);
    }
    function b( ) {
        alert(3);
    }
    function c( ) {
        alert(4);
    }

    window.setTimeout(fakeAsyncFunction, 1000);

    $(fakeAsync).on('customDone', a)
        .on('customDone', b)
        .on('customDone', c);
})(jQuery);

Working fiddle.

Kiruse
  • 1,703
  • 1
  • 12
  • 23
  • personally I don't really like setTimeout, I don't why I would have to wait, everything should be run ASAP when they are called, Also I am not that familiar with trigger events, maybe I need some review on that. Thx for your help anyway. – aptx May 19 '13 at 23:01
  • @aptx I used `setTimeout` here only to mimic the asynchronous behavior of your AJAX request. I could have made use of jsFiddle's AJAX API, but I barely ever use it and would have had to read into it. The events are simply used as your "global notification system" similar to the DOM events. Just hook up more listeners and you're done. – Kiruse May 20 '13 at 09:42