欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript 構(gòu)建一個xmlhttp對象池合理創(chuàng)建和使用xmlhttp對象

 更新時間:2010年01月15日 16:33:39   作者:  
在我的這篇舊文里曾經(jīng)發(fā)布了一個簡單的ajax操作類。我們發(fā)現(xiàn),在舊文里創(chuàng)建xmlhttp對象的時候,每次都要new一個對象。而我們都知道new一個對象的開銷是很大的。
如果我們在客戶端頻繁使用ajax技術,那么我們就不得不多次創(chuàng)建xmlhttp對象。當然,如您所知,我們可以改進創(chuàng)建的方式,比如使用全局變量來緩存一個實例(客戶端的單例模式?!),對于同步方式的通信,這是很有效的,但是這樣的方式對于異步通信會出現(xiàn)問題,因為沒有了進程的堵塞,用戶可能在上一次通信未完成時再次調(diào)用同一個xmlhttp實例,這樣不等前一個調(diào)用的回調(diào)函數(shù)觸發(fā),前一次調(diào)用就被“覆蓋”掉了(也就代表前一次調(diào)用失?。?。建立一個保持xmlhttp實例的池,好處顯而易見,最明顯的優(yōu)點就是我們不會創(chuàng)建冗余對象,同時也不會出現(xiàn)在同一個正在被調(diào)用的xmlhttp實例上出現(xiàn)再次被操作的情況。

具體實現(xiàn)思路:
我們使用一個數(shù)組來存儲已創(chuàng)建的xmlhttp對象實例,然后每次調(diào)用從池中去取一個實例。xmlhttp實例通訊完畢后我們不用做任何處置,因為它自身的readyState屬性可以標識出它是否可用,如果當時沒有空閑的xmlhttp實例,且池中的實例數(shù)小于最大實例個數(shù),那么就創(chuàng)建一個新的實例并放入池中。重新改進的實現(xiàn)代碼如下:
復制代碼 代碼如下:

//封裝XMLHTTP的MyAjaxObj類
var MyAjaxObj = new Object();
var maxXmlHttpCount = 5; //最多5個xmlhttp對象存在

MyAjaxObj.reqList = []; //可以清空里面的項

MyAjaxObj.getFreeObj = function() {
var req = null;
var len = this.reqList.length;
//先從當前的池里取
for (var i = 0; i < len; i++) {
if (this.reqList[i]) {
if (this.reqList[i].readyState == 4 || this.reqList[i].readyState == 0) {
req = this.reqList[i];
break;
}
}
}
//如果沒有閑置的對象,自己獨立創(chuàng)建
if (req == null) {
if (this.reqList.length < maxXmlHttpCount) {
req = getXmlHttp();
this.reqList.push(req);
}
}
return req;
}


//創(chuàng)建一個XMLHTTP對象,兼容不同的瀏覽器
function getXmlHttp() {
var xmlHttp = false;
var arrSignatures = ["MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try {
xmlHttp = new ActiveXObject(arrSignatures[i]);
return xmlHttp;
}
catch (oError) {
xmlHttp = false; //ignore
}
}
// throw new Error("MSXML is not installed on your system.");
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}
return xmlHttp;
}

/*封裝XMLHTTP向服務器發(fā)送請求的操作
url:向服務器請求的路徑;method:請求的方法,即是get/post;***callback:當服務器成功返回結(jié)果時,調(diào)用的函數(shù)(類似c#回調(diào)函數(shù))***
data:向服務器請求時附帶的數(shù)據(jù);urlencoded:url是否編碼;cached:是否使用緩存; callBackError;當服務器返回錯誤時調(diào)用的函數(shù)
*/
MyAjaxObj.send = function(url, method, callback, data, urlencoded, cached, callBackError) {
var req = this.getFreeObj(); //從池里或者直接實例化一個XMLHTTP的實例

//當XMLHTTP的請求狀態(tài)發(fā)生改變時調(diào)用 (核心處理函數(shù))
req.onreadystatechange = function() {
// 當請求已經(jīng)加載

if (req.readyState == 4) {
// 當請求返回成功
if (req.status == 200) { //或者 req.status < 400
// 當定義了成功回調(diào)函數(shù)時,執(zhí)行成功回調(diào)函數(shù)
if (callback)
callback(req, data);
}
// 當請求返回錯誤

else {
//當定義了失敗回調(diào)函數(shù)時,執(zhí)行失敗回調(diào)函數(shù)
if (callBackError)
callBackError(req, data);
}

// 有池的管理,我們可以省卻釋放資源的方法
// try {
// delete req;
// req = null;
// }
// catch (e) {
// alert(e.message);
// }
}
}

//如果以POST方式回發(fā)服務器
if (method.toUpperCase() == "POST") {
req.open("POST", url, true);
//請求是否需要緩存(只有在req.open之后才可以設置此項)
if (cached)
req.setRequestHeader("If-Modified-Since", "0");
//請求需要編碼
if (urlencoded)
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(data);
MyAjaxObj.reqList.push(req);
}
//以GET方式請求
else {
req.open("GET", url, true);
//請求是否需要緩存
if (cached)
req.setRequestHeader("If-Modified-Since", "0");
req.send(null);
MyAjaxObj.reqList.push(req);
}
return req;
}

//全部清除XMLHTTP數(shù)組元素,釋放資源
MyAjaxObj.clearReqList = function() {
var len = MyAjaxObj.reqList.length;
for (var i = 0; i < len; i++) {
var req = MyAjaxObj.reqList[i];
if (req) {
try {
delete req;
} catch (e) { }
}
}
MyAjaxObj.reqList = [];
}

//進一步封裝XMLHTTP以POST方式發(fā)送請求時的代碼
//isClear:是否清除XMLHTTP數(shù)組的所有元素;其他參數(shù)的意義見 MyAjaxObj.send
MyAjaxObj.sendPost = function(url, data, callback, isClear, isCached, callBackError) {
if (isClear) {
MyAjaxObj.clearReqList();
}
MyAjaxObj.send(url, "POST", callback, data, true, isCached, callBackError); //post方法需要編碼
}
//進一步封裝XMLHTTP以GET方式發(fā)送請求時的代碼
MyAjaxObj.sendGet = function(url, args, callback, isClear, isCached, callBackError) {
if (isClear)
MyAjaxObj.clearReqList();
return MyAjaxObj.send(url, "GET", callback, args, false, isCached, callBackError);
}

最后再ps:上周周末和一個哥們聊天的時候談到ajax應用中的xmlhttp對象。那哥們ms很“虔誠”地問我說xmlhttp怎么就異步通信了。我當時竟然毫不思索地說因為這個對象處理我們的請求調(diào)用是“異步”的(當然可以設置成同步的,不過這是一句廢話),當前這個請求不會影響其他的操作。這個回答是很“官方”的,顯然沒有說到問題的本質(zhì)。哥們,您的眼神兒有必要那么bs人么?現(xiàn)在稍作分析,個人認為其實每個xmlhttp異步請求都會觸發(fā)一個回調(diào)函數(shù),這個回調(diào)函數(shù)的調(diào)用不影響其他的操作,這個方法才是“異步”。如果對比c#里的異步處理回調(diào)方法,它們在原理上其實是相通的。 哈哈,現(xiàn)在終于想通了, 真是太驕傲,太有出息了,想到就興奮!

相關文章

  • 微信小程序計算器實例詳解

    微信小程序計算器實例詳解

    這篇文章主要為大家詳細介紹了微信小程序計算器實例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • JavaScript單元測試ABC

    JavaScript單元測試ABC

    在服務器端的單元測試中,都有各種各樣的測試框架,在JavaScript中現(xiàn)在也有一些很優(yōu)秀的框架,但在本文中,我們將自己動手一步步來實現(xiàn)一個簡單的單元測試框架
    2012-04-04
  • layui的表單驗證支持ajax判斷用戶名是否重復的實例

    layui的表單驗證支持ajax判斷用戶名是否重復的實例

    今天小編就為大家分享一篇layui的表單驗證支持ajax判斷用戶名是否重復的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-09-09
  • 微信小程序Vant組件庫的安裝與使用教程

    微信小程序Vant組件庫的安裝與使用教程

    之前推薦過的移動端web組件庫 Vant是Vue.js版本的,其對內(nèi)承載了有贊所有核心業(yè)務,對外有十多萬開發(fā)者在使用,一直是業(yè)界主流的移動端組件庫之一,下面這篇文章主要給大家介紹了關于微信小程序Vant組件庫的安裝與使用的相關資料,需要的朋友可以參考下
    2022-09-09
  • js canvas實現(xiàn)畫圖、濾鏡效果

    js canvas實現(xiàn)畫圖、濾鏡效果

    這篇文章主要為大家詳細介紹了js canvas實現(xiàn)畫圖、濾鏡效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • JavaScript不同場景下的文件下載方案詳解

    JavaScript不同場景下的文件下載方案詳解

    這篇文章主要為大家詳細介紹了JavaScript中不同場景下的三種常見文件下載方案,文中的示例代碼講解詳細,有需要的小伙伴可以參考一下
    2023-12-12
  • web3.js增加eth.getRawTransactionByHash(txhash)方法步驟

    web3.js增加eth.getRawTransactionByHash(txhash)方法步驟

    這篇文章主要介紹了web3.js增加eth.getRawTransactionByHash(txhash)方法步驟,需要的朋友可以參考下
    2018-03-03
  • JavaScript實現(xiàn)拖拽簡單效果

    JavaScript實現(xiàn)拖拽簡單效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)拖拽簡單效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JavaScript事件學習小結(jié)(一)事件流

    JavaScript事件學習小結(jié)(一)事件流

    這篇文章主要介紹了JavaScript事件學習小結(jié)(一)事件流的相關資料,需要的朋友可以參考下
    2016-06-06
  • JavaScript實現(xiàn)左側(cè)菜單效果

    JavaScript實現(xiàn)左側(cè)菜單效果

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)左側(cè)菜單效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論