场景:如果代码中需要多次执行Ajax请求,那么明智的做法是把创建这种对象的代码提取到一个类中,并创建一个包装器来包装在实际请求时所要经历的一系列步骤。简单工厂非常适合这种场合。
1 /*AjaxHandler interface*/ 2 var AjaxHandler = new Interface("AjaxHandler",["request","createXhrObject"]); 3 4 /*SimpleHandler class.*/ 5 var SimpleHandler = function(){}; 6 SimpleHandler.prototype = { 7 request:function(method,url,callback,postVals){ 8 var xhr = this.createXhrObject(); 9 xhr.onreadystatechange = function(){ 10 if(xhr.readyState !==4)return; 11 xhr.status === 200 ? callback.success(xhr.responseText,xhr.responseXML): 12 callback.failure(xhr.status); 13 }; 14 xhr.open(method,url,true); 15 if(method != "POST")postVals = null; 16 xhr.send(postVals); 17 }, 18 createXhrObject:function(){ 19 var methods = [ 20 function(){return new XMLHttpRequest();}, 21 function(){return new ActiveXObject("Msxml2.XMLHTTP");}, 22 function(){return new ActiveXObject("Microsoft.XMLHTTP");} 23 ]; 24 25 for(var i=0, len=methods.length;i<len;i++){ 26 try{ 27 methods[i](); 28 }catch(e){ 29 alert("error"); 30 continue; 31 } 32 console.log("method["+i+"]",methods[i]); //记住该方法 33 this.createXhrObject = methods[i]; 34 return methods[i](); 35 } 36 throw new Error("SimpleHandler:could not create an XHR object"); 37 } 38 } 39 40 var myHandler = new SimpleHandler(); 41 var callback = { 42 success:function(responseText){alert("success:" +responseText);}, 43 failure:function(statusCode){alert("statusCode"+statusCode);} 44 } 45 myHandler.request("get","a.php",callback); 46 //第二次请求Ajax,如果是chrome浏览器,那么调用createXhrObject的时候,this.createXhrObject直接存储的是methods[0];如果是老版本的IE,那么直接调用的是new ActiveXObject 47 myHandler.request("POST","b.php",callback,"username=zap");
说明:在首次执行时,它会依次尝试三种用于创建XHR对象的不同方法,一旦遇到一种管用的,他就会返回所创建的对象并将其自身改为用以创建那个对象的函数。这个函数摇身一变成了createXhrObject方法,这种技术称为memoizing,它可以用来创建存储着复杂计算的函数和方法,以免再次进行这种计算。