2009-12-18 69 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

相关问题