English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spiegazione dettagliata di XMLHttpRequest (1) richieste同步 e asincrone

XMLHttpRequest让发送一个HTTP请求变得非常简单。你只需要简单地创建一个请求对象实例,打开一个URL,然后发送这个请求。当传输完成后,结果的HTTP状态以及返回的响应内容也可以从请求对象中获取。 

通过XMLHttpRequest生成的请求可以通过两种方式来获取数据,异步模式或同步模式。请求的类型是由这个XMLHttpRequest对象的open()方法的第三个参数async的值决定的。如果该参数的值为false,则该XMLHttpRequest请求以同步模式进行,否则该过程将以异步模式完成。

两种通信模式:同步和异步请求: 

同步请求
 主线程中的同步请求会阻塞页面,由于对用户体验的糟糕影响,部分最新浏览器在主线程上的同步请求已经被弃用。在极少数情况下,使用同步模式的XMLHttpRequests比使用异步模式更合适。

 1.在Worker中使用XMLHttpRequest时,同步请求比异步请求更合适。
 主页中代码:

 <script type="text/javascript">
 var oMyWorker = new Worker("myTask.js"); 
 oMyWorker.onmessage = function(oEvent) { 
  alert("Worker disse: " + oEvent.data);
 };
 oMyWorker.postMessage("Hello");
</script>
myFile.txt (文件通过XMLHttpRequest对象同步请求):
Hello World!! 

包含Worker代码:myTask.js

 self.onmessage = function (oEvent) {
 if (oEvent.data === "Hello") {
var oReq = new XMLHttpRequest();
oReq.open("GET", "myFile.txt", false); // Richiesta sincrona
oReq.send(null);
self.postMessage(oReq.responseText);
 }
}; 

Attenzione: Poiché viene utilizzato Worker, questa richiesta è effettivamente asincrona.
 Puoi utilizzare un metodo simile per far interagire lo script con il server in background, precaricare alcuni contenuti. Per ulteriori dettagli, consulta l'uso di web workers

 2. Situazioni in cui è necessario utilizzare richieste sincrone
 In alcune circostanze rare, è possibile utilizzare richieste XMLHttpRequest sincrone. Ad esempio, nei gestori di eventi window.onunload e window.onbeforeunload. L'uso di XMLHttpRequest asincrono nel gestore di eventi page.unload può causare problemi: quando il riscontro viene restituito, la pagina non esiste più, tutti i variabili e callback sono stati distrutti. Il risultato è un errore, "funzione non definita". La soluzione è utilizzare richieste sincrone qui, in modo che la pagina non venga chiusa prima della completazione della richiesta.

 window.onbeforeunload = function () {
 var oReq = new XMLHttpRequest();
 oReq.open("GET", "logout.php?nick=" + escape(myName), false); // Richiesta sincrona
 oReq.send(null);
 if (oReq.responseText.trim() !== "已退出"); { // "已退出" è il dato di ritorno
return "Fallimento dell'uscita, vuoi eseguire manualmente l'uscita?";
 }
}; 

Richiesta asincrona
 Utilizzando il modello asincrono, quando i dati sono completamente richiesti, viene eseguito un callback specificato. Durante l'esecuzione della richiesta, il browser può eseguire normalmente altri trattamenti delle transazioni. 

3. Esempio: Creare un metodo standard per leggere file esterni
 In alcune situazioni, è necessario leggere più file esterni. Questa è una funzione standard. La funzione utilizza l'oggetto XMLHttpRequest per effettuare richieste asincrone. Inoltre, può specificare diversi callback funzionali per la lettura completata di ogni file.

 function loadFile (sURL, timeout, fCallback /*, 传入参数1, 传入参数2, 等 */) {
 var aPassArgs = Array.prototype.slice.call(arguments, 3), oReq = new XMLHttpRequest();
 oReq.ontimeout = function() {
console.log("La richiesta è scaduta.");
 }
 oReq.onreadystatechange = function() {
if (oReq.readyState === 4) { 
 if (oReq.status === 200) {
  fCallback.apply(oReq, aPassArgs);
 } else {
  console.log("Errore", oReq.statusText);
 }
}
 };
 oReq.open("GET", sURL, true);
 oReq.timeout = timeout;
 oReq.send(null);
} 

Uso del funzionamento della funzione loadFile:

 function showMessage (sMsg) {
 alert(sMsg + this.responseText);
}
loadFile("message.txt", 200, showMessage, "Nuovo messaggio!\\n"); 

La riga 1 definisce una funzione che, una volta completata la lettura del file, chiama la funzione fCallback con tutti i parametri successivi al terzo come propri parametri.
La riga 3 utilizza una configurazione di timeout per evitare che il tuo codice esegua per troppo tempo in attesa di leggere i dati di ritorno della richiesta, assegnando un valore all'attributo timeout dell'oggetto XMLHttpRequest.
 La riga 6 assegna al gestore dell'evento onreadystatechange una funzione di callback, che verifica in ogni esecuzione se la richiesta è terminata (lo stato della richiesta è 4), nel caso affermativo, verifica se la richiesta è stata eseguita con successo (lo stato HTTP è 200), nel caso affermativo, visualizza il codice sorgente della pagina, nel caso in cui la richiesta sia fallita, visualizza un messaggio di errore.
 La riga 15 specifica il terzo parametro come true, indicando che la richiesta dovrebbe essere eseguita in modalità asincrona.

 4. Esempio: utilizzo di richieste asincrone, senza usare closures.

 function switchXHRState() {
 switch (this.readyState) {
case 0: console.log("Il metodo open() non è stato chiamato."); break;
case 1: console.log("Il metodo send() non è stato chiamato."); break;
case 2: console.log("Il metodo send() è stato chiamato, le intestazioni di risposta e lo stato di risposta sono già stati restituiti."); break;
case 3: console.log("Scaricamento in corso, alcune parti dell'entità di risposta sono state ricevute."); break;
case 4: console.log("Richiesta completata!"); this.callback.apply(this, this.arguments);
 }
};
funzione loadFile (sURL, fCallback /*, argomento1, argomento2, ecc */) {
 var oReq = new XMLHttpRequest();
 oReq.callback = fCallback;
 oReq.arguments = Array.prototype.slice.call(arguments, 2);
 oReq.onreadystatechange = switchXHRState;
 oReq.open("GET", sURL, true);
 oReq.send(null);
} 

usando bind: 

function switchXHRState(fCallback, aArguments) {
 switch (this.readyState) {
case 0: console.log("Il metodo open() non è stato chiamato."); break;
case 1: console.log("Il metodo send() non è stato chiamato."); break;
case 2: console.log("Il metodo send() è stato chiamato, le intestazioni di risposta e lo stato di risposta sono già stati restituiti."); break;
case 3: console.log("Scaricamento in corso, alcune parti dell'entità di risposta sono state ricevute."); break;
case 4: console.log("Richiesta completata!"); fCallback.apply(this, aArguments);
 }
};
funzione loadFile (sURL, fCallback /*, argomento1, argomento2, ecc */) {
 var oReq = new XMLHttpRequest();
 oReq.onreadystatechange = switchXHRState.bind(oReq, fCallback, Array.prototype.slice.call(arguments, 2));
 oReq.open("GET", sURL, true);
 oReq.send(null);
}

Questo è tutto il contenuto dell'articolo, speriamo che sia utile per la tua apprendimento, e speriamo che tutti possano sostenere e applaudire le lezioni di tutorial.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright è di proprietà del rispettivo proprietario, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non possiede il diritto di proprietà, non è stato elaborato manualmente e non assume alcuna responsabilità legale. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare e fornire prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare