JS设计模式——7.工厂模式(示例-XHR)
XHR工厂
基本实现
var AjaxHandler = new Interface('AjaxHandler', ['request', 'createXHR']);
var SimpleHandler = function(){};
SimpleHandler.prototype = {
request: function(method, url, callback, postVars){
var xhr = this.createXHR();
xhr.onreadystatechange = function(){
if(xhr.readyState!==4) return;
(xhr.status===200)?
callback.success(xhr.responseText, xhr.responseXML):
callback.failure(xhr.status);
};
xhr.open(method, url, true);
if(method !== 'POST') postVars = null;
xhr.send(postVars);
},
createXHR: 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;
}
this.createXHR = methods[i]; //memoize the method.
return methods[i];
}
}
};
createXHR这个工厂方法根据当前的宿主环境返回适当的xhr对象.重点是createXHR在首次执行之后就被替换为了methods[i],这个就是memoizing技术了(可以称称之为记录).这样当我们下次用到createXHR的时候就不用在去能力检测了.大大的提升了性能.
SimpleHandler的调用如下:
var myHandler = new SimpleHandler();
var callback = {
success: function(responseText){
console.log('Success' + responseText);
},
failure: function(statusCode){
console.log('Failure' + statusCode);
}
};
myHandler.request('GET', 'stript.php', callback);
专用型连接对象
我们对上面的对象进行一个扩展,以便根据网络条件创建专门的请求对象.
首先我们先来创建两个新的处理器类:
1:QueHandler会在发起新的请求之前先确保所有请求都已经成功处理.
var QueHandler = function(){
this.queue = [];
this.requestInProgress = false;
this.retryDelay = 5;
};
extend(QueHandler, SimpleHandler);
QueHandler.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.createXHR();
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, true);}, that.retryDelay*1000);
}
}
};
xhr.open(method, url, true);
if(method!=='POST') postVars = null;
xhr.send(postVars);
}
};
QueHandler.prototype.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);
};
2:OffHandler会在用户处于离线状态时把请求缓存起来.
var OffHandler = function(){
this.storedRequests = [];
};
extend(OffHandler, SimpleHandler);
OffHandler.prototype.request = function(method, url, callback, postVars){
if(XhrManager.isOffline()){
this.storedRequests.push({
method:method,
url:url,
callback:callback,
postVars:postVars
});
}else{
this.flushStoredRequests();
OffHandler.superclass.request(method, url, callback, postVars);
}
};
OffHandler.prototype.flushStoredRequests = function(){
for(var i= 0, len=this.storedRequests.length; i<len; i++){
var req = this.storedRequests[i];
OffHandler.superclass.request(req.method, req.url, req.callback, req.postVars);
}
}
在运行时选择连接对象
现在该用到工厂模式了.因为程序元根本不知道各个最终用户面临的网络条件,所以要用一个工厂在运行是选择最合适的类.
var XhrManager = {
createXhrHandler: function(){
var xhr;
if(this.isOffline()){
xhr = new OffHandler();
}else if(this.isHighLatency()){
xhr = new QueHandler();
}else{
xhr = new SimpleHandler();
}
Interface.ensureImplements(xhr, AjaxHandler);
return xhr;
},
isOffline: function(){ //do a quick request with SimpleHandler and see if it success.
...
},
isHighLatency: function(){ //do a series of requests with SimpleHandler and time the requests,Best done once, as a branching function.
...
}
};
var myHandler = XhrManager.createXhrHandler();
var callback = {};
myHandler.request('GET', 'sript.php', callback);
我只想说他的isOffline的实现亮了.
XHR的三个重要属性
JS设计模式——7.工厂模式(示例-XHR)的更多相关文章
- JS设计模式——7.工厂模式(示例-RSS阅读器)
RSS阅读器 由于我们只想跟RSS容器对象打交道,所以用一个工厂来实例化这些内部对象并把它们组装到一个RSS阅读器中. 使用工厂方法在好处在于,我们创建的RSS阅读器类不会与那些成员对象紧密耦合在一起 ...
- [JS设计模式]:工厂模式(3)
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...
- js设计模式:工厂模式、构造函数模式、原型模式、混合模式
一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.a ...
- JS设计模式之工厂模式
1 什么是工厂模式? 工厂模式是用来创建对象的一种最常用的设计模式.我们不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂.工厂模式根据抽象程度的不同可以分为: ...
- JS设计模式--简单工厂模式
在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...
- JavaScript设计模式-10.工厂模式实例xhr
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JS设计模式——7.工厂模式(概念)
工厂模式 本章讨论两种工厂模式: 简单工厂模式 使用一个类(通常是一个单体)来生成实例. 使用场景:假设你想开几个自行车商店(创建自行车实例,组装它,清洗它,出售它),每个店都有几种型号的自行车出售. ...
- JavaScript设计模式--简单工厂模式例子---XHR工厂
第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...
- 设计模式——抽象工厂模式及java实现
设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
随机推荐
- [Linux] 关于 history 命令的简单使用
1. 如果不想记录当前 会话操作的命令的话 可以使用命令 set +o history 但是这个命令有一个坏处, 他自己被记住了... 2. 还有一个办法 就是 在退出登录之前执行命令 history ...
- Android事件分派机制
最近一直在学习Android里面的事件分派机制,感觉很奇妙,看了很多博客和分析,才在脑子里形成了一个模糊的概念,对事件分派有了一定的认识. 于是,我画了一个图来简单明了的表述Android中事件的分派 ...
- Python动态规划求解最长递增子序列(LIS)
原始代码错误,移步博客查看O(N^2)及优化的O(N*logN)的实现:每天一道编程题--最长递增子序列
- SecureCRT8.1下载+注册机+破解教程
[下载]下载SecureCRT + SecureFX 8.1 Bundle版本软件,官网下载较麻烦,因此在此提供百度云连接. 链接:http://pan.baidu.com/s/1hsIjtSK 密码 ...
- PHP 字符串数组按照拼音排序的问题
拼音排序的规则: 字符串包括特殊字符.数字.英文字符.中文字符等等,排序结果要求,特殊字符排在第一梯队,将其按照首个字符ascii码表进行排序,数字字符排在第二梯队,将首个字符数字按照数字大小排序,英 ...
- 单点登录(四)-----遇到问题-----cas server 源码部署tomcat运行报错ClassNotFoundException: org.jasig.cas.CasEnvironmentCo
情况 cas单点登录 cas server 源码部署tomcat运行报错 把cas server的代码下载下来后使用gradle插件或者maven插件以及转化成eclipse·后导入发现部署到tomc ...
- Git5:Git操作远程仓库
目录 说明 一.git clone 二.git remote 三.git fetch 四.git pull 五.git push 说明 Git有很多优势,其中之一就是远程操作非常简便.本文详细介绍5个 ...
- Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例)
Hadoop基础-Idea打包详解之手动添加依赖(SequenceFile的压缩编解码器案例) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑配置文件(pml.xml)(我 ...
- Spring整合Quartz定时任务 在集群、分布式系统中的应用
概述 虽然单个Quartz实例能给予你很好的Job调度能力,但它不能满足典型的企业需求,如可伸缩性.高可靠性满足.假如你需要故障转移的能力并能运行日益增多的 Job,Quartz集群势必成为你应用的一 ...
- element ui 上传文件,读取内容乱码解决
element ui 上传文件,读取内容乱码解决: 加第二个参数 reader.readAsText(file.raw,'gb2312'); <el-upload class="upl ...