0

I have the following function in a much larger script that loads translations from a php file:

function loadLanguages(language){
 var data = new Object();
 data.language = language;
 var dataString = $.toJSON(data);
 var langSt = $.ajax({
  url: "/VID/ajax/loadtranslations.php",
  data: ({data: dataString}),
  async: false
 }).responseText;
 var languageArr = $.evalJSON(langSt);
 return languageArr;
}

Works in FF, but in IE7 and IE8 the browser will hang.. When I comment out the ajax call in the function IE doesn't hang. If I set it to async: true the function doesn't work anymore, but the browsers will not hang. Only if I set async to false, IE will hang. I'm a bit puzzled why!

Gijserman
  • 61
  • 2
  • 3

2 Answers2

4

You should never use async: false; it will always hang the browser until the request finishes.

This is a necessary consequence of the fact that Javascript is single-threaded, and will never change.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • It doesn't *hang* the browser, it just makes it completely nonresponsive during the request. When the request completes, the browser becomes responsive again. Agree with the fundamental point, though: Don't do that. :-) – T.J. Crowder Jun 29 '10 at 14:02
  • *"...that Javascript is single-threaded, and will never change."* Actually, it will: http://www.w3.org/TR/workers/ – T.J. Crowder Jun 29 '10 at 14:03
  • @T.J.: I'm aware of that. However, it will not cause `async: false` to not hang. (Unless you run it in a worker) – SLaks Jun 29 '10 at 14:03
  • 1
    @Slaks: Exactly, it'll block (not hang) the worker thread, not the UI thread. But my point is that JavaScript on browsers *won't* be single-threaded forever. In fact, it's not *today*, not on Chrome at least. – T.J. Crowder Jun 29 '10 at 14:08
  • Problem is not that it hangs during the request, the problem is that it will keep hanging. IE will just stop working.. – Gijserman Jun 29 '10 at 14:12
  • That would happen if the request times out. Does it ever un-hang? – SLaks Jun 29 '10 at 14:15
  • It doesn't unhang, it basically crashes, there is no warning that a script is taking too long to respond or anything.. – Gijserman Jun 29 '10 at 14:19
  • Also, request shouldn't time out. It takes 250 ms in FireFox.. It's a request to a file on the same server too – Gijserman Jun 29 '10 at 14:35
1

Edit Sorry, you really meant hang (what you said); I and others just happily read block instead.

I notice you're using the responseText of the XMLHttpRequest object returned by $.ajax directly. I think even with a synchronous request, I'd still use the callback:

function loadLanguages(language){
    var data = new Object();
    data.language = language;
    var dataString = $.toJSON(data);
    var languageArr = /* ...some appropriate default value if the request fails... */;
    $.ajax({
        url: "/VID/ajax/loadtranslations.php",
        data: ({data: dataString}),
        async: false,
        success: function(langSt) {
            languageArr = $.evalJSON(langSt);
        }
    });
    return languageArr;
}

Old Answer:

When you use a synchronous Ajax request, on many browsers (not just IE), the user interface becomes completely nonresponsive during the request. On IE, it's particularly bad because it's not just your page, but the entire browser process that ends up waiting — the user can't even go off and do something else in another tab.

This leads to a poor user experience, to put it mildly.

It happens because for the moment, JavaScript on web browsers is single-threaded, and in many browsers, that thread is the UI thread. Even in non-browser-based applications, tying up the UI thread for non-UI processing is not ideal.

So you want to avoid using synchronous ajax requests whenever possible, and it's almost always possible (probably even always possible). It involves some refactoring in your approach, having function "A" start something that is later completed by function "B" (the "success" callack on the ajax call), but doing that refactoring (and then using that mindset in your design in the future) makes for a much better user experience overall.

Until web workers are widely implemented, you need to use that single JavaScript thread sparingly and think in terms of events and callbacks. I've found that being forced to do that actually improves my code in the end and is changing my approach to other environments for the better.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Well, sice it's a local request it shouldn't take too long to load, so the user's experience shouldn't be too poor (firefox does the request in 250 ms). But IE just crashes entirely, it doesn't stop for 250 ms or even 10 seconds.. – Gijserman Jun 29 '10 at 14:27
  • @Gijserman: I can't see any reason for it other than an IE bug. You'll need to identify *where* it hangs. In the `ajax` call? In the `toJSON` or `evalJSON`? You'll probably need the Script Debugger (or VS.Net if you have it) to figure this one out. Good luck. – T.J. Crowder Jun 29 '10 at 15:26