2013-03-04 2 views
0

У меня есть код JavaScript (ниже). В каждом случае, в конце цикла, $ sid должен быть равен нулю, но «alert ($ sid)» всегда дает мне 200. Я не могу найти ошибку в моем коде. Не могли бы вы мне помочь?Невозможно изменить переменную

Заранее спасибо.

$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; 
     } 
    }); 
} 
+13

Вы понимаете, что AJAX-вызовы асинхронны? –

+2

Чтобы переписать комментарий @Diodeus: Ajax-вызовы асинхронны. Это означает, что они могут вернуться в любое время. Ваш код запускает кучу запросов AJAX в цикле. Код цикла продолжает работать, пока ваши запросы AJAX обрабатываются асинхронно. Весь цикл может быть завершен до того, как будет возвращен первый запрос AJAX. – jahroy

+0

@jahroy хуже даже, обработчики успеха терпеливо ждут, пока цикл не будет завершен. –

ответ

2

Проблема в том, что вызов ajax является асинхронным. JavaScript помещает это, делает запрос на сервер, а затем переходит к следующей строке кода. Ваши функции обратного вызова успеха и ошибки не вызываются до тех пор, пока JavaScript не завершит выполнение вашего цикла while.

Кроме того, структура кода не имеет никакого смысла (извините, не пытаясь быть грубой). Переменные $ canAppend и $ iPage не используются или не изменяются. Что этот код будет делать, это ввести цикл и никогда не выйти. Почему это? Это связано с тем, что вызов $ .ajax() не блокируется. Он не будет ждать там, пока запрос не будет завершен, он будет продолжен. Поскольку JavaScript (по существу) однопоточный, обратные вызовы для ошибки и успеха НЕ МОГУТ исполняться до тех пор, пока не завершится текущий процесс выполнения. Поскольку не удается запустить обработчики ошибок и ошибок, $ sid не может быть установлен. Поскольку $ sid не может быть отправлен, код не может выйти из цикла while.

Я не вижу, как вы на самом деле используете код while. Вместо этого просто вызовите функцию $ .ajax() и обработайте результаты в вашем обработчике успеха. Попробуйте это сделать, чтобы вы могли лучше понять, что происходит:

$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 
-1

По умолчанию вызовов Ajax является асинхронным и функция успеха или ошибок откладываются до тех пор, после того, как $ .ajax извлечет TMP/result1.html. В вашем случае они будут отложены навсегда, потому что цикл while будет держать руку, $ sid останется равной 200, и вы будете продолжать накапливать аякс-вызовы.

Быстрое исправление, чтобы сделать ваш АЯКС синхронным вызова:

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

Переписывая свой код, чтобы избежать сочетаний в то время как петля и Ajax могут быть лучшей идеей (но я не знаю ваш конкретный контекст) ,

+3

I * очень * предположим * на * этот способ. 'async: false' закроет ваш браузер до тех пор, пока не будет выполнен вызов AJAX. –

+1

@RocketHazmat абсолютно, и именно поэтому я назвал это быстрым решением. Как sync ajax, так и в то время как петли обычно не лучшие практики, но трудно сказать без контекста. По крайней мере, здесь это хороший способ быстро понять проблему и перейти к чему-то лучшему. – Christophe

+0

И не заставляйте меня начинать с использования глобальных переменных ;-) Один шаг за шагом ... – Christophe

Смежные вопросы