2010-11-04 66 views
2

我有一些JavaScript可以觸發大約100次對php腳本的調用。 php腳本佔用大量內存並需要幾秒鐘才能完成,然後返回一個json響應通過或失敗。如何在沒有我的網頁凍結的情況下同步調用ajax

我不希望ajax調用是異步的,因爲服務器會停下來運行100個自己的實例,所以我嘗試使用同步,唯一的問題是它在調用腳本時凍結了網頁一次打電話。

我該如何一次性關閉一個ajax調用,而不是凍結我所在的頁面?

var a = []; 
    a[0] = 'test'; 
    a[1] = 'hello'; 
    a[2] = 'another'; 

$(document).ready(function(){ 
    $.each(a, function(k,v) { 
$.ajax({ 
    url:'/this-script-takes-a-few-seconds-to-complete.php', 
    async:false, 
    data: {foo: v}, 
    success: function(data){  
    console.log(data); 
    } 
}); 
    }); 
}); 
+14

...你在做什麼需要100個Ajax請求? – 2010-11-04 16:28:30

回答

14

你可以把在執行下一次調用的函數,並從您success處理程序調用該方法,像這樣:

$(function(){ 
    var i = 0; 
    function nextCall() { 
    if(i == a.length) return; //last call was last item in the array 
    $.ajax({ 
     url:'/this-script-takes-a-few-seconds-to-complete.php', 
     data: { foo: a[i++] }, 
     success: function(data){  
     console.log(data); 
     nextCall(); 
     } 
    }); 
    } 
    nextCall(); 
}); 

雖然...更好的辦法是不行100個電話,除非這是一個測試套件,否則我會重新訪問整個方法。

+2

注意:如果您從ajax回調的執行上下文中發出Ajax請求,IE6將會窒息。在setTimeout()中調用nextCall()調用以避免該問題(如果您的目標是IE6兼容性)。 – 2010-12-24 04:15:25

+0

@Nick:我需要100多個電話。建議的解決方案 – 2016-03-15 09:31:23

3

如果你不希望你的調用是異步的,那麼瀏覽器將無法更新將凍結的UI。爲什麼你不能使它異步?不要一次完成100個,只需等待一個完成,然後再撥打下一個。

+0

這樣做的最佳方式是什麼? – Paul 2010-11-04 16:28:30

+0

set i = 0;然後用[i]作爲參數調用,然後在完成時(使用成功函數),遞增i並再次調用它。當我== a.length,你完成了。 – 2010-11-04 16:30:02

0

很好用,問題是,阿賈克斯......代表「異步JavaScript和XML」 ......

試圖做阿賈克斯同步失敗擺在首位使用Ajax的目的。

嘗試使用線程池並運行它異步。

1

你需要重構這件事。 100個Ajax請求是瘋狂的,它們都是同步的。

我建議你重構你的應用程序,所以您可以分析所有數據併發送一個異步走,或一對夫婦異步請求,而不是100。

如果你需要100,使某種隊列和異步按順序處理它們。

+0

我假設他無法在一次通話中全部通話,因爲他想在每個請求之間更新ui。但是,如果他可以在一個請求中完成所有工作,那就打個電話。 – 2010-11-04 16:32:39

0

編輯 - 正確答案

大多數瀏覽器將HTTP請求的數量限制在一臺服務器,大概是爲了防止情況就像你正試圖阻止(服務器過載)。我不確定現代瀏覽器的實際數據是什麼,儘管我認爲它比2005年在Firefox中觀察到的舊「2」還要多。

一些資源:

老回答

該腳本將每2秒鐘調用一次同步$.ajax,每次將數據從數組a中移出。在每個請求實際執行期間,用戶界面仍然會鎖定,但會允許它在兩次調用之間自行更新。我認爲,這是在完全同步和完全異步之間的一個很好的妥協。

請注意,此腳本具有破壞性 - 完成後,a將爲空。如果您需要a的內容,那麼您可能需要創建一個副本。

a = [ 
    'test', 
    'hello', 
    'another' 
]; 

$(function() { 
    var send = function() { 
     $.ajax({ 
      url: '/this-script-takes-a-few-seconds-to-complete.php', 
      async: false, 
      data: {foo: a.shift()}, 
      success: function(data) { 
       console.log(data) 
      } 
     }); 

     if (!a.length) 
     { 
      clearInterval(timer); 
     } 
    } 

    var timer = setInterval(send, 2000); 
}); 
-1

我有類似的問題,我需要同步調用和IE瀏覽器凍結。總之我想出了這種方法。

  1. 而不是使用synchroniou調用我用async:true。
  2. 在完成:函數中遞歸調用next ajax請求。

它允許我不同尋常地呼叫同步呼叫,所以我在先前的呼叫之後呼叫。

+2

此解決方案在此問題的接受答案中提供。請在提供您自己的解決方案之前閱讀現有的解決方案,因爲這樣可以避免重複,而是在問題中添加其他信息。對於那些非常古老的問題,尤其如此,因爲社區可能已經無數次地回顧了Q&A,因此很少有任何可以改進的問題。哦,順便說一句,歡迎來到StackOverflow! – bPratik 2012-09-22 18:50:30

相關問題