views:

452

answers:

4

Hi

What I'm trying to do involves going through a series of checkboxes.

For each one of them that it is checked, I have to perform some calculations (using an ajax call). If there is an error, I have to break the loop and return a message.

Every ajax call takes about 0,4 seconds to perform but that shall never be a problem because I can only have a maximum of 4 of them checked at any given time.

But the problem I'm facing is that, the final alert box pops-up before the one inside the error function(). The error function does work but it appears always after the final one.

I was under the impression that by defining the call as asynchronous=false, code execution would wait until the call returned a response. Is that a wrong assumption?

Is there a way to accomplish this?

Thanks in advance

$("input[id*='chk_aut']").each(function() {
  if(this.value=="on") {
    $.ajax({
      type: "GET",
      url: "testpage.asp",
      cache:"false",
      async:"false",
      data: "which=checkvalues&value="
          + i_value
          + "&ref="+$("#cb_ref").val()
          + "&nif="+$("#txt_nif").val()
          + "&day="+i_day
          + "&month="+i_month
          + "&hours="+i_hours
          + "&year="+i_year + "&ms="
          + new Date().getTime(),
      success: function(msg) {
        //do something but continue the loop
      },
      error: function() {
        i_result =false;
        alert("An error has occurred");
        return false;//break the  loop
      }
    });
  }
});
alert(i_result);
A: 

I'm not familiar with the async option in the ajax call. I've been using the jQuery Ajax Manager with success for situations where I need synchronous ajax calls: http://plugins.jquery.com/project/AjaxManager

Chris Williams
Thanks for the tip. Seems worth looking deeper into.
Antonio Louro
+1  A: 

As mentioned in the manual, the error function is...

A function to be called if the request fails.

That is, if there's a communication problem between the client and the server (eg: timeout, no authorisation, etc). It's not called when your server-side script returns a value which in your application is considered an error. Move that code into success, and check the response data to see how your script treated each request.

Also, I should mention that you would need to have really good reasons to use synchronous calls. Yes, in your testing it only takes 1.5 seconds, but what happens when someone has a slow connection, or your server is under heavy load or unavailable? Synchronous requests freeze the client's browser (that is, not even things like changing tabs or scrolling works) and make for a very bad user experience. If you do want to block the UI on your page, there's plenty of friendlier ways to do it. For example, check out BlockUI.

It is much better to use callbacks and start thinking asynchronously, rather than procedurally. It's a bit of a struggle when you first start (since your code isn't necessarily run in line-by-line order), but it is very powerful and flexible once you get the hang of it.

nickf
I know the error function isn't supposed to be called in that situation. In an attempt to clarify the code I pasted some in the wrong place. Edited now and thanks for the heads up. Voted your comment up.
Antonio Louro
+3  A: 

I think you need to use

,async: false

So that you pass the boolean false, not the string "false". That should make your AJAX call synchronous.

See this question for a similar situation and some more details. In particular, you may find that for synchronous AJAX calls you can't use the success handler and must return results once your call has completed (you're out of the scope of the AJAX call itself).

If at all possible you should try to restructure your code so that it can work asynchronously. Synchronous execution does not translate well to the browser.

In your situation, if you are using each AJAX call to accumulate results for each checkbox that is checked, consider storing the working value in a window variable and keeping track of which requests have returned. When you determine that you have received a successful response back for each of the AJAX calls you initiated, you can kick off your alert box or whatever else you want to do with the results. That is just one example of how you can start thinking asynchronously.

Gene Goykhman
I will try to use the async parameter the way you described it. I do have a replacement code for this situation (not using async:false) but I was curious as to why it wasn't working the intended way.
Antonio Louro
Already tried to use the boolean but to no avail.Still the same results.
Antonio Louro
Applied your suggestion to the cache parameter and everything works as expected. Thank you for the time you took to answer this.
Antonio Louro
A: 

Use async:false in case of async:"false"and enjoy

Anirudha Biswas