天天看點

自動排隊的異步Ajax請求自動排隊的異步Ajax請求

自動排隊的異步Ajax請求

發表于 2010年04月18日 由 admin

這兩天正在為Ajax同步請求會臨時鎖住浏覽器的問題而煩惱,沒想到今天在看《JavaScript設計模式》發現了解決方法,裡面有一段可以自動排隊的異步Ajax請求的代碼範例。看到這段代碼真有種衆裡尋她千百度,蓦然回首,那人卻在燈火闌珊處的感覺,哈哈。現在把它整理下,用着慢慢用。

var QueuedHandler = function(){
	this.queue = []; // 請求隊列
	this.requestInProgress = false; // 判斷目前是否己有别的請求
	this.retryDelay = 5; // 設定每次重新請求的時間,機關為秒
};
QueuedHandler.prototype = {
	request:function(method,url,callback,postVars,override){
        // 如果沒有設定為覆寫模式,而且目前已經有别的請求
        if(this.requestInProgress && !override){
            this.queue.push({
                method:method,
                url:url,
                callback:callback,
                postVars:postVars
            });
		}else{
            this.requestInProgress = true;
            var xhr = this.createXhrObject();
            var that = this;

            xhr.onreadystatechange = function(){
                if(xhr.readyState !== 4) return;
                if(xhr.status === 200){
                    callback.success(xhr.responseText,xhr.responseXML);
                    // 判斷請求隊列是否為空,如果不為空繼續下一個請求
                    that.advanceQueue();
                }else{
                    callback.failure(xhr.status);
                    // 每過一定時間重新請求
                    setTimeout(function(){
                        that.request(method,url,callback,postVars);
                    },that.retryDelay * 1000);
                }
            };

            xhr.open(method,url,true);
            if(method!=='POST')postVars = null;
            xhr.send(postVars);
        }
	},
	createXhrObject:function(){
        var methods = [
            function(){return new XMLHttpRequest();},
            function(){return new ActiveXObject('Msxml2.XMLHTTP');},
            function(){return new ActiveXObject('Microsoft.XMLHTTP');},
        ];
        for(var i=0,len=methods.length;i<len;i++){
            try{
           	 methods[i]();
            }catch(e){
            	continue;
            }
            // 如果執行到這裡就表明 methods[i] 是可用的
            this.createXhrObject = methods[i]; // 記住這個方法,下次使用不用再判斷
            return methods[i]();
		}

		throw new Error('SimpleHandler: Could not create an XHR object.');
	},

	advanceQueue:function(){
        if(this.queue.length === 0){
            this.requestInProgress = false;
            return;
        }
        var req = this.queue.shift();
        this.request(req.method,req.url,req.callback,req.postVars,true);
	}
};
           

用以下方法調用,你會發現,除第一個請求外,其它的請求都會在上一個請求完全完成後才執行的。

var myHandler = new QueuedHandler();
var callback = {
	success:function(reponseText){console.log('Success');},
	failure:function(statusCode){console.log('Failure');}
};
myHandler.request('GET','feedProxy.php?feed=http://julabs.me/blog/feed/rss/',callback);
myHandler.request('GET','feedProxy.php?feed=http://julabs.me/blog/feed/rss/',callback);
myHandler.request('GET','feedProxy.php?feed=http://julabs.me/blog/feed/rss/',callback);
myHandler.request('GET','feedProxy.php?feed=http://julabs.me/blog/feed/rss/',callback);
           

繼續閱讀