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. Java并发编程之线程创建和启动(Thread、Runnable、Callable和Future)

    这一系列的文章暂不涉及Java多线程开发中的底层原理以及JMM.JVM部分的解析(将另文总结),主要关注实际编码中Java并发编程的核心知识点和应知应会部分. 说在前面,Java并发编程的实质,是线程 ...

  2. 【刷题】BZOJ 4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  3. 【2018ICPC青岛】

    B 题意:给n个问题,每个问题有一个固定的答案ai(<=10^5).现在有m个约束关系,每个约束关系是一个二元组(ui,vi),表示你回答ui.vi问题的答案必须一样. 现在让你输出分别修复一个 ...

  4. 【poj2411】 Mondriaan's Dream

    http://poj.org/problem?id=2411 (题目链接) 题意 一个$n*m$的网格,用$1*2$的方块填满有多少种方案. Solution 轮廓线dp板子.按格dp,对上方和左方的 ...

  5. 【bzoj1078】 SCOI2008—斜堆

    http://www.lydsy.com/JudgeOnline/problem.php?id=1078 (题目链接) 题意 给出一个斜堆,并给出其插入的操作,求一个字典序最小的插入顺序. Solut ...

  6. ThinkPHP 5.x远程命令执行漏洞分析与复现

    0x00 前言 ThinkPHP官方2018年12月9日发布重要的安全更新,修复了一个严重的远程代码执行漏洞.该更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的 ...

  7. Metasploit+python生成免杀exe过360杀毒

    Metasploit+python生成免杀exe过360杀毒 1在kali下生成一个反弹的msf的python脚本,命令如下: msfvenom -p windows/meterpreter/reve ...

  8. 编译安装nrpe,配置监控mysql端口和主从状态

    1.安装插件 # tar xvf nagios-plugins-1.4.13.tar.gz # cd nagios-plugins-1.4.13 # ./configure # make && ...

  9. Java之高级IO,Properties

    IO流(高级) 释放资源的标准代码 主要考虑的是在什么时候释放资源比较合适.而且在jdk1.7之前和之后是不同的. package com.wzlove.demo; import java.io.Fi ...

  10. nodejs进程异常退出处理方法

    1. 捕获uncaughtException process.on('uncaughtException', function (err) { //打印出错误 console.log(err); // ...