zoukankan      html  css  js  c++  java
  • 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的三个重要属性

  • 相关阅读:
    数据库迁移至ASM
    获取数据库或SHEME的DDL语句
    membership配置数据库(SQL2000)
    DIV+CSS到底是什么?
    如何更改表的所有者权限
    windows server 2003 上“您要访问的网页有问题,无法显示。HTTP 500 内部服务器错误。”的问题解决方案!
    瞎忙
    瞎忙
    如何更改表的所有者权限
    DIV+CSS到底是什么?
  • 原文地址:https://www.cnblogs.com/JChen666/p/3631009.html
Copyright © 2011-2022 走看看