4

I have a code that calls $.ajax like this :

$.ajax({

                        type: "POST",
                        url: "/sandbox/graphloader/mock3",
                        async: false,
                        data: {calInput1:dates[0], calInput2:dates[1]},
                        success: function(data){
                            data=eval(data);
                            for(var x in data[0]){
                                //alert(data[0][x]);
                                //fill columns here;
                            }

                            fillPercents(column);
                        }});

now, this works in all browsers, other than Firefox. firebug shows it is getting reply back from post, but for some unknown error, it is not displaying the data. What might be the problem ?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Shrinath
  • 7,888
  • 13
  • 48
  • 85
  • The problem is firefox never finishes loading. I am using a jquery ui for showing columns that are populated with data returned from ajax, the data never gets populated. – Shrinath Nov 17 '10 at 04:11
  • What happens if you put a `console.log` or `alert` call at the beginning of the callback? Do you see any errors in Firebug? – SLaks Nov 17 '10 at 04:14
  • What type of data is returned by the ajax call(ie json, xml, html etc)... can you give a sample... Whether your eval function is returning successfully? – Arun P Johny Nov 17 '10 at 04:36
  • alert responds. it just doesn't fill up the data. looks like it hangs in.. and no errors in firebug. – Shrinath Nov 17 '10 at 04:37
  • before putting async:false, the data was being represented properly. the data passed is json, from php, a multidimension array. – Shrinath Nov 17 '10 at 04:38
  • then you can set a property `dataType:'json'` in the ajax call then no need to use `eval()` to process the data. jQuery will process the data and pass it as the `data` argument. Can you put a break point in the firebug and try to see what is going wrong – Arun P Johny Nov 17 '10 at 04:49
  • dude, data is fine imho, the flow is fine, I am just seeing it inconsistent if I remove async:false. if I put it back, it doesn't work in firefox, but works in other browsers. – Shrinath Nov 17 '10 at 04:56

3 Answers3

11

This behavior is by design.

Never use async: false.
Since Javascript runs on the UI thread, an async: false request will freeze the browser until the server replies.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • "until server replies" is ok. let it freeze. but once the server replies, it should be normal right ?? – Shrinath Nov 17 '10 at 04:11
  • 1
    **No, DON'T let it freeze**. This is the surest (OK, almost surest) way to drive users away from your site. – SLaks Nov 17 '10 at 04:13
  • I see... ok, then I have a new problem. My ajax calls are supposed to fill 4 columns with data from server after a user changes date on the column. then there are calculations on this new data. I've also put the calculations part in the "success" function of jquery's ajax call. but the calculations are happening on the old data "sometimes". Can I avoid this ?? – Shrinath Nov 17 '10 at 04:16
  • You're probably running them before the server replies. Can you show your code? – SLaks Nov 17 '10 at 04:21
  • original question updated to show the ajax call.. if you want more, let me know.. – Shrinath Nov 17 '10 at 04:33
  • Are those calculations in the success callback of the ajax call or have you placed them after the ajax call(ie in the next line after $.ajax()) – Arun P Johny Nov 17 '10 at 04:34
  • @arun : By "calculations" you mean the function fillPercents(i) ? it is a function call dude, it is called "in" the $.ajax(), but the function is outside the ajax's success callback. Should it be the problem ?? – Shrinath Nov 17 '10 at 04:40
  • @Shrinath ~ Listen to @SLaks one more time. **DON'T let it freeze** ... there's just no reason to use synchronous code from javascript. Instead, block the UI in some other fashion to notify the user that you're still working. But **DON'T let it freeze** – jcolebrand Nov 17 '10 at 04:58
  • ok, lets remove async:false, but the fillPercents() seems to be taking old data, and not the new data that came from ajax. This doesn't happen always, but sometimes. Shows inconsistent behaviour – Shrinath Nov 17 '10 at 05:11
  • shall we use setTimeout("fillPercents("+column+")",2000); to delay the calculation of percentages ?? – Shrinath Nov 17 '10 at 05:12
  • @Shrinath: At the very least, you should pass a function to setTimeout, not a string. However, you should be able to debug this problem. – SLaks Nov 17 '10 at 14:41
  • @SLaks: but dude, setTimeout() takes a function name as a string :) "fillPercents(columnNumber)" is my function to calculate percentages :) – Shrinath Nov 19 '10 at 18:40
  • And dude, setting delay for fillpercents did solve the problem. I guess it was taking the old data in columns to calculate the percents. Now I set a delay of 100ms, and it is working fine.. Now its working WITHOUT "async:false" and with setTimeout("fillpercents(columnNumber)",100); – Shrinath Nov 19 '10 at 18:42
  • @Shrinath: No. `setTimeout` takes a function. You should not pass a string. Instead, write `setTimeout(function() { fillpercents(columnNumber); }, 100); ` – SLaks Nov 19 '10 at 19:14
  • @SLaks : what about this ? : http://www.w3schools.com/js/js_timing.asp And I am using the same syntax which is working. What is the advantage of using the function instead of string ?? – Shrinath Nov 22 '10 at 06:01
  • 3
    @Shrinath: Passing a function is much faster. Do not look to W3Scoohls for best practices. – SLaks Nov 22 '10 at 12:15
1

Your columns global might be getting overwritten by a previous AJAX request.

Try making it a local variable in the callback, and try adding console.log calls to ensure that the callback order is what you expect.


You may need to keep a global request counter to ensure that you don't process a response after sending a new request.

For example:

var lastRequest = 0;   //You may want to put this in a namespace or closure

...

var thisRequest = ++lastRequest;
$.ajax({
    type: "POST",
    url: "/sandbox/graphloader/mock3",
    async: false,
    data: {calInput1:dates[0], calInput2:dates[1]},
    success: function(data){
        if (thisRequest !== lastRequest) return;
        ...
    }});

Do not do this inside a loop body or you'll share the thisRequest variable.
Instead, call a function from the loop body.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

It's freezing because it's not getting a 'success' response and you haven't handled the error. Set an error: function(jqXHR, textStatus, errorThrown){} in you settings to handle the error response. async: false works fine.

shivers999
  • 11
  • 1