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实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
随机推荐
- jquery 半透明遮罩效果 小结
最近偏离学术的道路越来越远了!! 今天要小结的是实现一个半透明遮罩效果.点击页面上的一个按钮,立即在屏幕的正中央显示某个部件,并且在这个部件之外的区域像是蒙上了一层半透明的遮罩.点击遮罩区域,该正中央 ...
- TeX-换行换页与段落命令
换行换页与段落命令1 UTF8nsung Abstract 文档在排版时往往要求每一行具有相同的长度, LATEX 为了对整段的文挡进行优化,将插入必要的换行和空恪.如果必要的话对于一行中不好放的单词 ...
- mysql内外连接
更新于2017-12-13,在今天的一个面试里面被问到了left/right outer join,回答上来了.但又问了一下inner join ,一下子记不清inner jion是个什么东西了.这次 ...
- Timing wheel心跳机制
在web服务中,断开空闲连接是一种减少资源浪费的一种手段,由此就有了心跳机制来判断一个连接是否空闲. 一种简单粗暴的方式: 1. 服务端每个连接保存一个最后一次操作的时间戳,每次这个连接对应fd可读时 ...
- thread 学习
#include <thread> #include <cstdio> #include <utility> #include <iostream> v ...
- RocketMQ生产者消息篇
系列文章 RocketMQ入门篇 RocketMQ生产者流程篇 RocketMQ生产者消息篇 前言 上文RocketMQ生产者流程篇中详细介绍了生产者发送消息的流程,本文将重点介绍发送消息的通信模式以 ...
- 注册系统所有的dll文件.bat
@echo off echo 运行后,能重新注册系统所有的dll文件, echo 能解决内存读写错误的问题 pause echo on for %%1 in (%windir%/system32/*. ...
- 【BZOJ4025】二分图(线段树分治,并查集)
[BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...
- 【模板】网络流-最大流模板(Dinic)
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> u ...
- Redis事务介绍
概述 相信学过Mysql等其他数据库的同学对事务这个词都不陌生,事务表示的是一组动作,这组动作要么全部执行,要么全部不执行.为什么会有这样的需求呢?看看下面的场景: 微博是一个弱关系型社交网络,用户之 ...