0

I have some JavaScript code (below). In every case, at the end of the loop the $sid should be zero, but "alert($sid)" always give me 200. I can't find an error in my code. Could you please help me?

Thanks in advance.

$sid = 200;
$canAppend = 0;
$iPage = 1;

while ($sid && $canAppend==0 && $iPage==1) {
    alert($sid);
    $.ajax({
    url: "tmp/result1.html",
    success: function(html)
    {
        if(html)
        {
            $("#inzeraty").append(html);
            $('div#loadmoreajaxloader').hide();
            $sid = 0;
        }            
    },
    error: function()
        {
            $sid = 0;
        }
    });
}
Viliam Jobko
  • 305
  • 3
  • 8
  • 13
    Do you understand that AJAX calls are asynchronous, right? – Diodeus - James MacFarlane Mar 04 '13 at 19:23
  • 2
    To re-word the comment by @Diodeus: Ajax calls are asynchronous. That means they can return at any time. Your code kicks off a bunch of AJAX requests in a loop. The looping code continues to run while your AJAX requests are processed asynchronously. Your entire loop might be complete before the first AJAX request returns. – jahroy Mar 04 '13 at 19:31
  • @jahroy worse even, the success handlers keep waiting patiently until the loop is complete. – John Dvorak Mar 04 '13 at 19:34

2 Answers2

2

The issue is that the ajax call is asynchronous. JavaScript puts this makes the request to the server and then continues on to the next line of code. Your success and error callback functions are not being called until after JavaScript has completed execution of your while loop.

Furthermore, the structure of the code doesn't make any sense at all (sorry, not trying to be rude). The $canAppend and $iPage variables are not used or changed. What this code will do is enter into a loop and never exit. Why is this? It's because the call to $.ajax() is non blocking. It won't wait there until the request is completed, it will continue on. Since JavaScript is (essentially) single threaded the callbacks for error and success CAN'T be executed until the current execution process is completed. Because the success and error handlers can't be run the $sid can't be set. Because $sid can't be sent the code can't exit the while loop.

I don't see how you code is actually making use of the while loop. Instead, just call the $.ajax() function and handle the results in your success handler. Try this on for size to help you better understand what's going on:

$sid = 200;

alert("$sid is 200: " + $sid); // you'll see this first

$.ajax({
    url: "tmp/result1.html",
    success: function(html)
    {
        if(html)
        {
            $("#inzeraty").append(html);
            $('div#loadmoreajaxloader').hide();
            $sid = 0;
            alert("$sid is now 0: " + $sid); // you'll see this third if html is not false
        } else {
            alert("$sid is STILL 200: " + $sid); // you'll see this third if html is false
        }
    },
    error: function()
    {
        $sid = 0;
        alert("you got an error, but $sid is now 0: " + $sid); // you'll see this third if there's an error
    }
});

alert("$sid is still 200: " + $sid); // you'll see this second
Doug Hughes
  • 931
  • 1
  • 9
  • 21
-1

By default ajax calls are asynchronous and the success or error functions are postponed until after $.ajax has retrieved tmp/result1.html. In your case, they'll be postponed forever because the while loop will keep the hand, $sid will remain equal to 200 and you'll keep piling up ajax calls.

A quick fix is to make your ajax call synchronous:

$.ajax({
  url: "tmp/result1.html",
  async: false,
  success: function(html)
// etc.

Rewriting your code to avoid a mix of while loop and ajax might be a better idea (but I don't know your specific context).

Christophe
  • 27,383
  • 28
  • 97
  • 140
  • 3
    I *highly* suggest *against* this method. `async: false` will make your browser lock up until the AJAX call is done. – gen_Eric Mar 04 '13 at 19:36
  • 1
    @RocketHazmat absolutely, and this is why I called this a quick fix. Both sync ajax and while loops are usually not best practices, but it's hard to tell without the context. At least here it is a good way to quickly understand the issue and move on to something better. – Christophe Mar 04 '13 at 19:39
  • And don't get me started on the use of global variables ;-) One step at a time... – Christophe Mar 04 '13 at 19:42
  • True, this may show him what's going on, I just wanted to put that warning there, just in case. – gen_Eric Mar 04 '13 at 19:43