国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

詳解XMLHttpRequest(一)同步請求和異步請求

2024-05-06 16:32:00
字體:
來源:轉載
供稿:網友

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 said: " + 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); // 同步請求oReq.send(null);self.postMessage(oReq.responseText); }}; 

注意: 由于使用了Worker,所以該請求實際上也是異步的.
 可以使用類似的方法,讓腳本在后臺與服務器交互,預加載某些內容.查看使用web workers了解更多詳情

 2.不得不使用同步請求的情況
 在少數情況下,只能使用同步模式的XMLHttpRequest請求.比如在 window.onunload和window.onbeforeunload 事件處理函數中。在頁面unload事件處理函數中使用異步的XMLHttpRequest會引發這樣的問題:當響應返回之后,頁面已經不復存在,所有變量和回調函數也已經銷毀.結果只能引起一個錯誤 ,“函數未定義”。解決辦法是在這里使用同步模式的請求,這樣的話,當請求完成之前,頁面不會被關閉.

 window.onbeforeunload = function () { var oReq = new XMLHttpRequest(); oReq.open("GET", "logout.php?nick=" + escape(myName), false); // 同步請求 oReq.send(null); if (oReq.responseText.trim() !== "已退出"); { // "已退出"是返回的數據return "退出失敗,您想手動執行退出嗎?"; }}; 

異步請求
 使用異步模式的話,當數據完全請求回來以后,會執行一個指定的回調函數, 在執行請求的同時,瀏覽器可以正常的執行其他事務的處理。 

3.例子: 創建一個標準的方法來讀取外部文件
 在一些需求情況下,必須讀取多個外部文件. 這是一個標準的函數. 該函數使用XMLHttpRequest對象進行異步請求.而且可以為每個文件讀取完成后指定不同的回調函數.

 function loadFile (sURL, timeout, fCallback /*, 傳入參數1, 傳入參數2, 等 */) { var aPassArgs = Array.prototype.slice.call(arguments, 3), oReq = new XMLHttpRequest(); oReq.ontimeout = function() {console.log("請求超時."); } oReq.onreadystatechange = function() {if (oReq.readyState === 4) {  if (oReq.status === 200) {  fCallback.apply(oReq, aPassArgs); } else {  console.log("Error", oReq.statusText); }} }; oReq.open("GET", sURL, true); oReq.timeout = timeout; oReq.send(null);} 

loadFile函數的用法:

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

第1行定義一個函數,當文件讀取完畢后,fCallback函數會以第3個參數以后的所有參數為自己的參數來被調用.
第3行使用一個超時設置,來避免你的代碼為了等候讀取請求的返回數據長時間執行,通過為XMLHttpRequest對象的timeout 屬性賦值來指定
 第6行為onreadystatechange事件句柄指定了回調函數,函數在每次執行時,檢查請求是否結束(請求狀態為4),如果是的話,判斷請求是否成功(HTTP狀態嗎是否為200),如果是的話,輸出頁面源碼,如果請求出現了錯誤,輸出錯誤信息.
 第15行指定第三個參數為true,表示該請求應該以異步模式執行.

 4.例子: 使用異步請求,不使用閉包.

 function switchXHRState() { switch (this.readyState) {case 0: console.log("還沒調用open()方法."); break;case 1: console.log("還沒調用send()方法."); break;case 2: console.log("已經調用send()方法,響應頭和響應狀態已經返回."); break;case 3: console.log("下載中,已經得到部分響應實體."); break;case 4: console.log("請求完成!"); this.callback.apply(this, this.arguments); }};function loadFile (sURL, fCallback /*, 傳入參數1, 傳入參數2, 等 */) { 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);} 

使用 bind: 

function switchXHRState(fCallback, aArguments) { switch (this.readyState) {case 0: console.log("還沒調用open()方法."); break;case 1: console.log("還沒調用send()方法."); break;case 2: console.log("已經調用send()方法,響應頭和響應狀態已經返回."); break;case 3: console.log("下載中,已經得到部分響應實體."); break;case 4: console.log("請求完成!"); fCallback.apply(this, aArguments); }};function loadFile (sURL, fCallback /*, 傳入參數1, 傳入參數2, 等 */) { var oReq = new XMLHttpRequest(); oReq.onreadystatechange = switchXHRState.bind(oReq, fCallback, Array.prototype.slice.call(arguments, 2)); oReq.open("GET", sURL, true); oReq.send(null);}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 合川市| 鄯善县| 息烽县| 南投县| 彝良县| 繁峙县| 卫辉市| 寿阳县| 汤阴县| 江孜县| 双辽市| 安泽县| 新疆| 甘德县| 新建县| 漳州市| 嵊泗县| 农安县| 固阳县| 驻马店市| 奉贤区| 柯坪县| 蒙城县| 于田县| 扬州市| 新田县| 平陆县| 朝阳区| 虞城县| 改则县| 来宾市| 东城区| 山阳县| 北碚区| 赣榆县| 田林县| 商南县| 特克斯县| 万山特区| 南昌市| 东乌珠穆沁旗|