2009-12-18 13 views
8

Sto cercando di configurare una pagina Web che campiona i dati tramite chiamate AJAX da un server web incorporato. Come impostare il codice in modo che una richiesta non si sovrapponga ad un'altra? Vorrei menzionare che ho pochissima esperienza di JavaScript e anche un motivo valido per non usare librerie esterne di qualsiasi dimensione più grandi di forse 10 o più kilobyte.Come posso effettuare chiamate Ajax a intervalli senza sovrapposizione?

+6

Benvenuti in StackOverflow. Ottima prima domanda. – Sampson

risposta

1

AJAX, nonostante il nome, non deve essere asincrono.

Ecco il metodo asincrono ...

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

... ma qui è un equivalente sincrono ...

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

... e qui è una tipica azione ...

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

le richieste sincrone non sono proprio l'idea migliore, a mio parere, bloccano anche il resto della pagina .... ma questo dipende dai requisiti dell'utente. inoltre, da jQuery $ .ajax docs: "È meglio bloccare l'interazione dell'utente con altri mezzi quando la sincronizzazione è necessaria." –

0

vi suggerisco di utilizzare un piccolo kit di strumenti come jx.js (source). Lo si può trovare qui: http://www.openjs.com/scripts/jx/ (meno di 1k minified)

Per impostare una richiesta:

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

impostarlo su un intervallo è possibile utilizzare setInterval e una variabile per memorizzare o meno di una richiesta di è attualmente si verificano - se lo è, noi non facciamo niente semplice:

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

Come l'altra risposta ... Quindi, perché sprecare l'intervallo, piuttosto basta effettuare chiamate sincrone. Scaricherà in media 5000ms/2 mediante polling. – dacracot

6

si può prendere in considerazione la possibilità di rilanciare la vostra richiesta AJAX solo dopo una risposta positiva dalla chiamata AJAX precedente.

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

questo esempio utilizza ExtJS, ma si potrebbe facilmente utilizzare solo XMLHttpRequest.

NOTA: Se è necessario disporre di un intervallo esatto di x secondi, si dovrebbe tenere traccia del tempo trascorso dal momento in cui la richiesta AJAX è stato lanciato fino alla chiamata setTimeout(), e quindi sottrarre questo periodo da il ritardo. In caso contrario, il tempo di intervallo nell'esempio precedente varierà con la latenza della rete e con il tempo necessario per elaborare la logica del servizio Web.

+0

non esattamente quello che stavano chiedendo, ma un'ottima soluzione (solo per usare le callback) –

+1

Buona risposta. Comunque probabilmente vorrai 'setTimeout' dopo che le precedenti chiamate Ajax sono state fatte, indipendentemente dal fatto che sia andata a buon fine o meno. Altrimenti, la prima volta che si ha un timeout o un errore si smetterà di ricevere aggiornamenti. – Grodriguez

Problemi correlati