1

I have the following code, and for some odd reason, the order in which the events are happening is not making sense to me. Is there anyway in which I can make it so that it goes in the order?

var vm_good = false;
console.log("Before", vm_good);
    $.post("./ajax/call_price", {id: product_id}, function(data){
        $.each(data, function(key, value){
           $(".unit-price span").html(value);
        });
        vm_good = true;
        console.log("Inside", vm_good);
        enableNext();
    }, 'json');
    console.log("After", vm_good);

And the results on the console window is:

>Before false
>After false
>Inside true
>window.vm_good // I called it manually after the page loaded
>>true
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 3
    Welcome to the wonderful world of **async**! This behavior is by design. – SLaks Apr 22 '13 at 15:19
  • 1
    The post request is asynchronous. It does not block. The interpreter moves on and continues processing, then handles that once the server has responded. – nbrooks Apr 22 '13 at 15:19

2 Answers2

2

.post() is an asynchronous request. that means JS doesn't wait for it to finish, it just move on to next instruction.

You need to put console.log("After", vm_good); inside your post callback like this-

var vm_good = false;
console.log("Before", vm_good);
    $.post("./ajax/call_price", {id: product_id}, function(data){
        $.each(data, function(key, value){
           $(".unit-price span").html(value);
        });
        vm_good = true;
        console.log("Inside", vm_good);
        enableNext();

        console.log("After", vm_good); // you should put this here
    }, 'json');
Adil Shaikh
  • 44,509
  • 17
  • 89
  • 111
2

$.post is a shorthand of $.ajax. A in AJAX stands for asynchronous, so interpreter will execute next command, while $.post will run your event handler (function(data)) when your request is done. If your request wouldn't be asynchronous then your browser would freeze, because it would wait for your request to finish.

You can use $.when(deffered).then(handler) to execute code after your request is done:

var callPrice = $.post("./ajax/call_price", {id: product_id}, function(data){
    $.each(data, function(key, value){
       $(".unit-price span").html(value);
    });
    vm_good = true;
    console.log("Inside", vm_good);
    enableNext();
}, 'json');

$.when(callPrice).then(function () {
    console.log("After", vm_good);
});
Zbigniew
  • 27,184
  • 6
  • 59
  • 66
  • Thank you, this is exactly what I needed. Thanks for the helpful information as well =) –  Apr 22 '13 at 15:42