2016-07-27 9 views
1

Ich arbeite an meinem ersten AJAX-Projekt, und ich habe durch die Einrichtung folgende Funktionen gestartet:Wie verwalte ich mehrere überlappende XMLHttpRequests?

function sendHTTPRequest(callback,filename,data) { 

    if (window.XMLHttpRequest) { 
     httpRequest = new XMLHttpRequest(); 
    } else if (window.ActiveXObject) { 
     httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

    httpRequest.onreadystatechange = callback; 
    httpRequest.open('POST',rootAddress+filename, true); 
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    httpRequest.send(data); 

} 

function exampleCallback() { 

    if (httpRequest.readyState === XMLHttpRequest.DONE) { 
     if (httpRequest.status === 200) { 
      // successful, parse the XML data 
     } else { 
      // error 
     } 
    } else { 
     // not ready 
    } 
} 

Das hat gut funktioniert, aber ich habe jetzt zu dem Punkt, wo ich mehr als eine habe gleichzeitige HTTP-Anfrage, und meine einzige globale httpRequest Variable schneidet es nicht. Es scheint mir, ich könnte ein Array verwenden, und .push eine neue XMLHttpRequest auf den Stapel jedes Mal sendHTTPRequest() aufgerufen wird, aber wie kann ich meine verschiedenen Callback-Funktionen, die Element im Stapel zu parsen? Oder ist das ein besserer Weg, diesen Prozess zu bewältigen? (Ich verwende diese, um Anfragen an verschiedene Seiten zu bearbeiten, mit Ergebnissen, die anders geparst werden müssen.)

Vielen Dank!

Antwort

2

Verwenden Sie eine lokale Variable und einen Callback pro Anfrage, der wiederum den angegebenen Callback aufruft. Die erforderlichen Änderungen sind überraschend gering; siehe ** Linien:

function sendHTTPRequest(callback,filename,data) { 
    var httpRequest; // ** Local variable 

    if (window.XMLHttpRequest) { 
     httpRequest = new XMLHttpRequest(); 
    } else if (window.ActiveXObject) { 
     httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 
    } 

    // ** Callback specific to *this* request 
    httpRequest.onreadystatechange = function() { 
     if (httpRequest.readyState === XMLHttpRequest.DONE) { 
      if (httpRequest.status === 200) { 
       // successful, call the callback 
       callback(httpRequest); 
      } else { 
       // error, call the callback -- here we use null to indicate the error 
       callback(null); 
      } 
     } else { 
      // not ready 
     } 
    }; 
    httpRequest.open('POST',rootAddress+filename, true); 
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    httpRequest.send(data); 
} 

function exampleCallback(xhr) { 

    if (xhr) { 
     // successful, parse the XML data, for instance 
     var x = xhr.responseXML; 
    } else { 
     // not ready 
    } 
} 

Man könnte es dem Rückruf mehr Informationen hat, geben (zum Beispiel der filename und data Argumente).

Wenn Sie Versprechungen verwenden, können Sie sendHTTPRequest ein Versprechen zurückgeben, anstatt einen direkten Rückruf zu akzeptieren.

+1

Ich weiß, wir sollen "Danke" Beiträge vermeiden, aber das ist wirklich unglaublich hilfreich und informativ. Danke für deine klare Erklärung und Verbesserungen! – TobyRush

2
httpRequest = new XMLHttpRequest(); 

Sie eine globale nicht verwenden. Verwenden Sie eine lokale Variable.

if (httpRequest.readyState === XMLHttpRequest.DONE) { 

Sie eine globale nicht verwenden. Event-Handler werden im Kontext des Objekts aufgerufen, auf das sie feuern. Verwenden Sie this.

Verwandte Themen