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实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
随机推荐
- Windows下 OpenSSL的安装与简单使用
1. openssl的最新版本 最新版本是 openssl1.1.1 官方地址 https://www.openssl.org/source/ TLS1.3的协议(RFC8446)在2018.8.12 ...
- 在输入密码框中眼睛睁开可以看见数字,眼睛闭上看不见数字怎么用JS实现
无论做那个项目,登录注册页面总是避免不了的,那怎么用js来控制密码的显示和隐藏呢?先看一下效果图: HTML代码如下: <div> <label for=" ...
- Whitecoin区块链钱包高级功能使用命令
格式:NO-命令-命令概要-主要对象-参数 <必须参数> [可选参数]-含义-描述-需要未锁定钱包 1 addmultisigaddress 新增多重签名地址 地址 <nrequ ...
- UESTC 1832
今天比赛的时候做的一个题目.感觉这个题目不错. 题目描述: Description In a laboratory, an assistant, Nathan Wada, is measuring w ...
- struts下载文件
- BZOJ 3143 游走(贪心+期望+高斯消元)
一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分 ...
- NIO - 三大组件
NIO 概述 NIO有三个核心组件: 通道(Channels) 缓存(Buffers) 选择器(Selectors) 实际上,NIO的组件和类远不止这三个,但这个三个组件是核心.至于其它组件,例如Pi ...
- 【agc019C】Fountain Walk
Portal --> agc019C Description 有一个\(10^8*10^8\)的网格图,一格距离为\(100\),第\(x\)条竖线和第\(y\)条横线的交点记为\((x,y)\ ...
- activiti教程之示例项目activiti-explorer运行_百度经验
https://jingyan.baidu.com/article/4e5b3e19107ad091901e249e.html
- 公钥与私钥对HTTPS的理解(数字证书的需要)
本文转自某大牛链接 文中首先解释了加密解密的一些基础知识和概念,然后通过一个加密通信过程的例子说明了加密算法的作用,以及数字证书的出现所起的作用.接着对数字证书做一个详细的解释,并讨论一下window ...