2011-08-15 55 views
2
 var hasData = '1'; 
     while (hasData != 0) { 
      $.ajax({ 
      url: '/ajax.php?updateRow='+hasData, 
      dataType: 'json', 
      async: false, 
      success: function(data) { 
       hasData = data.next; 
       $('.result').append(data.html); 
       } 
      }); 

應該發生什麼: 從PHP([html]和[next])拉出的JSON數組。如果[next]設置爲0(當沒有更多條目時) - while循環停止,應該是這樣。當我在JavaScript中告訴它時while循環不會結束

發生了什麼事情: 除了 - 當滿足while()要求(所以當hasData設置爲0時)時,應該做的所有事情 - 循環進入無限循環(並且它始終請求最後一個條目。 ..直到腳本變爲「無響應」)

+9

Ajax請求是異步的! –

+4

但是,如果您設置了「async:false」,則不適用。除非我們對名稱一無所知,在這種情況下,我們也應該告訴他使用XML ... –

+3

同步Ajax請求在請求期間讓瀏覽器的UI無響應。 **從不**使用'async:false'。 – duri

回答

6

ajax發送一個請求並在有響應時執行回調。那麼是什麼發生的事情是:

  • 火的請求
  • 消防另一個請求
  • 消防另一個請求
  • 消防另一個請求
  • ...

,因爲它是一個while循環。你用請求堵塞你的腳本,服務器得到一堆可能無法處理的請求。編輯:對不起,我錯過了async: false。但是,這總是會使瀏覽器不響應。做的最好的事情是使用async: true,並觸發另一如果條件是這麼說的,但你的反應後,才:

function check() { 
     $.ajax({ 
     url: '/ajax.php?updateRow='+hasData, 
     dataType: 'json', 
     async: true, 
     success: function(data) { 
      hasData = data.next; 
      $('.result').append(data.html); 
      if(hasData != 0) check(); // do it again 
      } 
     }); 
} 

check(); // fire the first request 

由於Spycho指出,因爲你獲取JSON,更方便的方法可能成爲:

(function() { 

    var fireRequest = function() { // this function is not available anywhere else, 
            // to avoid having this process running more than once 

     $.getJSON('/ajax.php', {updateRow: hasData}, function(data) { 
      hasData = data.next; 
      $('.result').append(data.html); 
      if(hasData != 0) fireRequest(); // do it again 
     }); 

    }; 

    fireRequest(); // start the process 

})(); // call it 
+1

您可能希望從使用$ .ajax切換到[$ .getJSON](http://api.jquery.com/jQuery.getJSON/),因爲它稍微整齊一些,會提出相同的請求。 – Spycho

+1

我認爲你的答案中有一個錯字。您推薦'async:true',然後在您的解決方案中寫入'async:false'。 – Spycho

+0

@Spycho:的確,感謝您的反饋! – pimvdb

1

AJAX中的第一個字母表示「異步」。瀏覽器不會在初始$.ajax()調用後等待響應,而是多次調用此函數。

var hasData = 1; 
function ajaxRequest() { 
    $.ajax({ 
     //... 
     success: function(data) { 
      hasData = data.next; 
      $('.result').append(data.html); 
      if (hasData != 0) 
      { 
       ajaxRequest(); 
      } 
     } 
    }); 
} 
+1

「Async:false」應該阻止這種情況發生。 –

+0

@Grim瀏覽器的UI在非異步請求期間停止響應。永遠不要這樣做。 – duri

+1

我沒有,但OP做到了。在再次調用函數之前,我也會試着稍微延遲一下,以免在沒有任何結果的情況下敲擊帶寬。 –

0

我也建議你投你的響應數據數字,如

hasData = data.next * 1;

因爲有時即使JSON返回一個數字,它不被認爲是一些通過JavaScript和比較

hasData!= 0

成真,即使hasData = 「0」 ...

+0

這不起作用:/ – Norris

4

實際上,您的代碼所做的並不遠離您自己的服務器上的拒絕服務攻擊:)

Ajax請求在完成之前不會阻塞,因爲其他人已經指出。調用$.ajax立即返回,實際請求在後臺執行並在完成時調用success回調。這一切意味着Javascript以儘可能快的速度遍歷while,因爲沒有什麼能夠阻止它。這也意味着,當你的第一個請求嘗試完成時,Javascript可能會產生成千上萬的新請求,這些請求都需要服務器處理。

您的服務器將變得不舒服,同時提供如此多的請求並且速度變慢(如果您檢查它的CPU和內存使用情況,您會注意到)。由於服務器速度變慢,Javascript會產生越來越多的請求......直到最終整個系統停止運行,因爲Javascript可能耗盡了資源和服務器。

A while循環不建議你的情況。最好一次發送一個請求,並檢查success回調中的返回值。如果尚未0,請產生另一個請求,然後重複該過程。

function updateRows(onCompleted) { 
    $.ajax({ 
     url: '/ajax.php?updateRow='+hasData, 
     dataType: 'json', 
     success: function(data) { 
      hasData = data.next; 
      if (hasData == 0) { 
       return onCompleted(); 
      }  

      $('.result').append(data.html); 
      updateRows(onCompleted); // not finished yet, recursion 
     } 
    }); 
} 

onCompleted論點是,一旦你的更新過程完成了被執行的回調函數。您可以如下使用它:

updateRows(function() { 
    // Now all rows are updated 
    // Proceed with program flow 
}); 
+1

它不是異步的。但其餘的答案是非常正確的。 –

+0

謝謝,我重新制定了這一部分。 – emboss

+0

謝謝你的解釋,幫助了很多:) – Norris

0

因爲您已將異步設置爲false,所以瀏覽器將掛起,直到響應可用。你的腳本可能沒有陷入無限循環,而只是等待響應。

檢查您的服務器端腳本實際工作。