2009-12-18 57 views
8

我正在設置一個網頁,通過來自嵌入式Web服務器的AJAX調用對數據進行採樣。我將如何設置代碼以便一個請求不會與另一個請求重疊? 我應該提到我有很少的JavaScript體驗,也是一個令人信服的理由,不使用任何大小可能大於10千字節的外部庫。如何在不重疊的情況下進行Ajax調用?

+6

歡迎來到StackOverflow。偉大的第一個問題 – Sampson 2009-12-18 22:18:53

回答

1

AJAX儘管名稱不必是異步的。

這裏是異步方法...

var req; 

function ajax(method,url,payload,action) 
    { 
    if (window.XMLHttpRequest) 
     { 
     req = new XMLHttpRequest(); 
     req.onreadystatechange = action; 
     req.open(method, url, true); 
     req.send(payload); 
     } 
    else if (window.ActiveXObject) 
     { 
     req = new ActiveXObject("Microsoft.XMLHTTP"); 
     if (req) 
      { 
      req.onreadystatechange = action; 
      req.open(method, url, true); 
      req.send(payload); 
      } 
     else 
      { 
      alert("Could not create ActiveXObject(Microsoft.XMLHTTP)"); 
      } 
     } 
    } 

...但這裏是一個同步相當於...

function sjax(method,url,payload,action) 
    { 
    if (window.XMLHttpRequest) 
     { 
     req = new XMLHttpRequest(); 
     req.open(method, url, false); 
     req.send(payload); 
     action(); 
     } 
    else if (window.ActiveXObject) 
     { 
     req = new ActiveXObject("Microsoft.XMLHTTP"); 
     if (req) 
      { 
      req.onreadystatechange = action; 
      req.open(method, url, false); 
      req.send(payload); 
      } 
     else 
      { 
      alert("Could not create ActiveXObject(Microsoft.XMLHTTP)"); 
      } 
     } 
    } 

...這裏是一個典型的動作...

function insertHtml(target) 
    { 
    var pageTarget = arguments[0]; 
    if (req.readyState == 4) // 4 == "loaded" 
     { 
     if (req.status == 200) // 200 == "Ok" 
      { 
      if (req.responseText.indexOf("error") >= 0) 
       { 
       alert("Please report the following error..."); 
       pretty = req.responseText.substring(req.responseText.indexOf("error"),1200); 
       pretty = pretty.substring(0,pretty.indexOf("\"")); 
       alert(pretty + "\n\n" + req.responseText.substring(0,1200)); 
       } 
      else 
       { 
       div = document.getElementById(pageTarget); 
       div.innerHTML = req.responseText; 
       dimOff(); 
       } 
      } 
     else 
      { 
      alert("Could not retreive URL:\n" + req.statusText); 
      } 
     } 
    } 
+0

同步請求並不是最好的主意,在我看來,它們鎖定了頁面的其餘部分......但這取決於用戶的要求。另外,從jQuery $ .ajax文檔:「最好是在需要同步時用其他方式阻止用戶交互。」 – 2009-12-19 04:21:42

0

我建議你使用一個小工具包,如jx.js(source)。你可以在這裏找到它:http://www.openjs.com/scripts/jx/(小於1K精縮)

要設置一個請求:

jx.load('somepage.php', function(data){ 
    alert(data); // Do what you want with the 'data' variable. 
}); 

要設置它在某個區間,你可以使用setInterval和變量來存儲是否請求目前存在的 - 如果是這樣,我們簡單做什麼:

var activeRequest = false; 
setInterval(function(){ 

    if (!activeRequest) { 
     // Only runs if no request is currently occuring: 
     jx.load('somepage.php', function(data){ 
      activeRequest = false; 
      alert(data); // Do what you want with the 'data' variable. 
     }); 
    } 
    activeRequest = true; 

}, 5000); // Every five seconds 
+0

與其他答案一樣......那麼爲什麼要浪費時間間隔,而只是進行同步呼叫。您通過投票平均浪費5000ms/2。 – dacracot 2009-12-18 22:45:39

6

你可能要考慮從以前的AJAX調用成功的響應後,ONLY然後重新打開AJAX請求的選項。

function autoUpdate() 
{ 
    var ajaxConnection = new Ext.data.Connection(); 

    ajaxConnection.request(
    { 
     method:   'GET', 
     url:   '/web-service/', 

     success: function(response) 
     { 
      // Add your logic here for a successful AJAX response. 
      // ... 
      // ... 

      // Relaunch the autoUpdate() function in 5 seconds. 
      setTimeout(autoUpdate, 5000); 
     } 
    } 
} 

本例使用ExtJS,但你可以很容易地只使用XMLHttpRequest

注:如果你必須有X秒一個確切的時間間隔,你必須追蹤從當AJAX請求發起到setTimeout()調用中傳遞的時間,然後減去從這個時間跨度延時。否則,上述示例中的間隔時間將隨網絡延遲和處理Web服務邏輯的時間而變化。

+0

不完全是他們要求的,但一個非常好的解決方案(只使用回調) – 2009-12-19 04:22:50

+1

好的答案。但是,在先前的Ajax調用完成後,您可能希望設置「setTimeout」,而不管它是否成功。否則,第一次出現超時或錯誤時,您將停止獲取更新。 – Grodriguez 2011-09-10 08:52:57

相關問題