I got the following Request Queue implementation from this blog:
http://dsgdev.wordpress.com/2006/10/28/building-a-javascript-http-request-queue/
and want to wrap it with a object variable. Unfortunately the variable initialization inside doesn't work.
Hope someone can help me with this stuff. Thanks in advance
var requestQueue = { inCall : false, // VARIABLE TO TRACK IF WE ARE CURRENTLY IN A CALL callToArray : new Array(), // QUEUE FOR CALLS returnToArray : new Array(), // QUEUE FOR FUNCTION TO EXECUTE WHEN CALL 开发者_如何学GoCOMPLETE reqMethodArray : new Array(), // QUEUE FOR REQUEST METHOD createRequestObject : function(){ var reqObj; var browser = navigator.appName; if(browser == "Microsoft Internet Explorer"){ reqObj = new ActiveXObject("Microsoft.XMLHTTP"); isIE = true; }else{ reqObj = new XMLHttpRequest(); } return reqObj; }, sendCall : function(whereTo, returnTo, reqMethod){ // GET THE NEXT ARRAY ITEM AND REMOVE FROM THE ARRAY this.callToArray.push(whereTo); this.returnToArray.push(returnTo); if (reqMethod != "GET" || reqMethod != "POST") { reqMethod = "GET"; } this.reqMethodArray.push(reqMethod); }, callQueue : function(){ // CHECK THE QUEUE AND SEND THE NEXT CALL IN LINE if(!this.inCall && this.callToArray.length > 0){ // DO WE HAVE ANYTHING IN THE QUEUE? if(this.callToArray.length > 0){ // WE DO, SO GET THE FIRST ITEM IN THE CALL ARRAY AND REMOVE IT whereTo = this.callToArray.shift(); returnTo = this.returnToArray.shift(); reqMethod = this.reqMethodArray.shift(); // SEND THAT CALL this.doCall(whereTo, returnTo, reqMethod); }else{ // UPDATE DEBUG QUEUE } }else{ // UPDATE DEBUG QUEUE } }, doCall : function(whereTo, returnTo){ this.inCall = true; var http = this.createRequestObject(); http.open('get', whereTo); // DO WE HAVE A FUNCTION TO CALL ONCE CALL IS COMPLETED? if(returnTo.length > 0){ eval("http.onreadystatechange = " + returnTo); } // SEND CALL http.send(null); } }; setInterval(requestQueue.callQueue, 100);
setInterval(requestQueue.callQueue, 100);
Peels off the callQueue
method from requestQueue
and passes it to setInterval
. Consequently callQueue
has no reference to requestQueue
; when it is called back, this
will be set to window
not requestQueue
so the attempt to evaluate this.callToArray.length
will cause an error.
this
in JavaScript does not work in the way you would expect from any other language. See this question for an explanation. If you only have one requestQueue
instance you can just reference that instead of using this
, otherwise you'll need to look into function binding or a closure.
Incidentally I'd not recommend UA-string-sniffing for detecting the right XHR object to use. Try feature-sniffing instead:
var r= window.XMLHttpRequest? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
(this would also use native XMLHttp on IE7+ where enabled, potentially avoiding an ActiveX prompt.)
精彩评论