2009-12-18 6 views
8

Ich möchte eine Webseite einrichten, die Daten über AJAX-Aufrufe von einem eingebetteten Webserver abfragt. Wie würde ich den Code so einrichten, dass sich eine Anfrage nicht überschneidet? Ich sollte erwähnen, ich habe sehr wenig JavaScript-Erfahrung und auch ein zwingender Grund, keine externen Bibliotheken jeder Größe größer als vielleicht 10 oder so Kilobyte zu verwenden.Wie mache ich Ajax-Anrufe in Intervallen ohne Überlappung?

+6

Willkommen bei StackOverflow. Tolle erste Frage. – Sampson

Antwort

1

AJAX muss trotz des Namens nicht asynchron sein. Hier

ist die asynchrone Methode ...

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)"); 
      } 
     } 
    } 

... aber hier ist ein synchroner Äquivalent ...

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)"); 
      } 
     } 
    } 

... und hier ist eine typische Aktion ...

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

synchrone Anfragen sind nicht wirklich die beste Idee, sie sperren meiner Meinung nach auch den Rest der Seite ... aber das hängt von den Anforderungen des Benutzers ab. auch aus jQuery $ .ajax docs: "Es ist besser, die Benutzerinteraktion mit anderen Mitteln zu blockieren, wenn eine Synchronisation erforderlich ist." –

0

ich schlage vor, Sie ein kleines Toolkit wie jx.js verwenden (source). Sie können es hier finden: http://www.openjs.com/scripts/jx/ (weniger als 1k minimiert)

Zur Einrichtung einer Anfrage:

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

es auf einem Intervall einzurichten Sie setInterval und eine Variable zu speichern, ob eine Anforderung verwenden können zur Zeit ist vorkommendes - wenn es ist, wir einfach nichts tun:

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

Wie die andere Antwort ... Warum also das Intervall verschwenden, sondern nur synchrone Anrufe machen. Sie werden im Durchschnitt 5000ms/2 durch Umfragen verschwenden. – dacracot

6

möglicherweise möchten Sie die Möglichkeit, Neubelebung Ihrer AJAX-Request nur nach einer erfolgreichen Antwort von der vorherigen AJAX-Aufruf zu betrachten.

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); 
     } 
    } 
} 

Dieses Beispiel verwendet ExtJS, aber man kann sehr leicht nur XMLHttpRequest verwenden.

HINWEIS: Wenn Sie ein genaues Intervall von x Sekunden haben müssen, würden Sie den Überblick über die Zeit von weitergegeben zu halten, wenn der AJAX-Request wurde den setTimeout() Aufruf gestartet, und dann subtrahieren diese Zeitspanne von die Verzögerung. Andernfalls variiert die Intervallzeit im obigen Beispiel mit der Netzwerklatenz und mit der Zeit für die Verarbeitung der Webservice-Logik.

+0

nicht genau das, was sie gefragt haben, aber eine sehr gute Lösung (nur um Rückrufe zu verwenden) –

+1

Gute Antwort. Allerdings möchten Sie wahrscheinlich 'setTimeout' nach den vorherigen Ajax-Aufrufen tun, unabhängig davon, ob es erfolgreich ist oder nicht. Andernfalls erhalten Sie beim ersten Mal, wenn Sie ein Timeout oder einen Fehler haben, keine Updates mehr. – Grodriguez