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)的更多相关文章

  1. JS设计模式——7.工厂模式(示例-RSS阅读器)

    RSS阅读器 由于我们只想跟RSS容器对象打交道,所以用一个工厂来实例化这些内部对象并把它们组装到一个RSS阅读器中. 使用工厂方法在好处在于,我们创建的RSS阅读器类不会与那些成员对象紧密耦合在一起 ...

  2. [JS设计模式]:工厂模式(3)

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

  3. js设计模式:工厂模式、构造函数模式、原型模式、混合模式

    一.js面向对象程序 var o1 = new Object();     o1.name = "宾宾";     o1.sex = "男";     o1.a ...

  4. JS设计模式之工厂模式

    1 什么是工厂模式? 工厂模式是用来创建对象的一种最常用的设计模式.我们不暴露创建对象的具体逻辑,而是将将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂.工厂模式根据抽象程度的不同可以分为: ...

  5. JS设计模式--简单工厂模式

    在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...

  6. JavaScript设计模式-10.工厂模式实例xhr

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. JS设计模式——7.工厂模式(概念)

    工厂模式 本章讨论两种工厂模式: 简单工厂模式 使用一个类(通常是一个单体)来生成实例. 使用场景:假设你想开几个自行车商店(创建自行车实例,组装它,清洗它,出售它),每个店都有几种型号的自行车出售. ...

  8. JavaScript设计模式--简单工厂模式例子---XHR工厂

    第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...

  9. 设计模式——抽象工厂模式及java实现

    设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...

随机推荐

  1. BZOJ5104 Fib数列(二次剩余+BSGS)

    5在1e9+9下有二次剩余,那么fib的通项公式就有用了. 已知Fn,求n.注意到[(1+√5)/2]·[(1-√5)/2]=-1,于是换元,设t=[(1+√5)/2]n,原式变为√5·Fn=t-(- ...

  2. mysql时间函数和时间操作

    补 原文链接:http://blog.csdn.net/yuxiayiji/article/details/7480785 select timediff('23:40:00', ' 18:30:00 ...

  3. c++11 语言级线程

    c++11 语言级线程 线程的创建 用std::thread创建线程非常简单,只需要提供线程函数或函数对象即可,并且可以同时指定线程函数的参数. #define _CRT_SECURE_NO_WARN ...

  4. BZOJ5058 期望逆序对 【矩乘 + 组合数学 + 树状数组】

    题目链接 BZOJ5058 题解 可以发现任意两个位置\(A,B\)最终位置关系的概率是相等的 如果数列是这样: CCCCACCCCBCCCC 那么最终有\(7\)种位置关系 \((A,B)\) \( ...

  5. Fork/Join框架实现原理

    ForkJoinPool由ForkJoinTask数组和ForkJoinWorkerThread数组组成,ForkJoinTask数组负责存放程序提交给ForkJoinPool的任务,而ForkJoi ...

  6. 一次绕过防火墙获取RCE以及提权到root权限的渗透过程

    本文是关于Apache struts2 CVE-2013-2251是由于导致执行远程命令的影响而被高度利用的漏洞.简而言之, 通过操纵以“action:”/”redirect:”/”redirectA ...

  7. java多线程 -- Condition 控制线程通信

    Api文档如此定义: Condition 将 Object 监视器方法(wait.notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对 ...

  8. python之旅:三元表达式、列表推导式、生成器表达式、函数递归、匿名函数、内置函数

    三元表达式 #以下是比较大小,并返回值 def max2(x,y): if x > y: return x else: return y res=max2(10,11) print(res) # ...

  9. python之旅:文件处理

    一 文件操作及理论 1. 介绍 计算机系统分为:计算机硬件.操作系统.应用程序三部分我们用python或者其他程序,想要把数据永久的保存下来,就得写到硬盘里,但是应用程序是没有办法直接操作硬件的,这就 ...

  10. BRIEF特征点描述子

    简介 BRIEF是2010年的一篇名为<BRIEF:Binary Robust Independent Elementary Features>的文章中提出,BRIEF是对已检测到的特征点 ...