zoukankan      html  css  js  c++  java
  • 状态模式全解析--JavaScript

    1 初级电灯例子 , 状态仅仅用字符串表示,没有封装到对象

    class Light{
        constructor(){
            this.state = 'off';
            let button = document.createElement( 'button' );
            button.innerHTML = '开关';
            this.button = document.body.appendChild( button );
            this.button.onclick = ()=>{
                this.buttonWasPressed();
            }
        }
        buttonWasPressed(){
            if ( this.state === 'off' ){
                console.log( '开灯' );
                this.state = 'on';
            }else if ( this.state === 'on' ){
                console.log( '关灯' );
                this.state = 'off';
            }
        }
    
    }
    new Light();

    //  状态模式----面向对象版本

      实现的关键

      1 状态用对象表示

      2 状态对应的行为 抽象成一个统一的方法(buttonWasPressed),可以实现委托。这个行为可以放到状态类里,也可以放到context里,

      3 状态内部 会自己修改当前的状态,(也就是下一个状态是什么,在每一个状态对象内部已经明确,)

      4 当触发操作开始时,会用当前状态调用当前状态对应的行为,从而成功避免了使用丑陋的if else 分支,

     1 class State{
     2     buttonWasPressed(){
     3         throw new Error( '父类的 buttonWasPressed 方法必须被重写' )
     4     }
     5 }
     6 
     7 class StrongLightState extends State{
     8     constructor(light){
     9         super();
    10         this.light = light
    11     }
    12     // buttonWasPressed(){
    13     //     console.log('-->关灯');
    14     //     this.light.setState(this.light.offLightState)
    15     // }
    16 }
    17 
    18 class OffLightState  extends State{
    19     constructor(light){
    20         super();
    21         this.light = light
    22     }
    23     buttonWasPressed(){
    24         console.log('-->弱光');
    25         this.light.setState(this.light.weakLightState)
    26     }
    27 }
    28 
    29 class WeakLightState  extends State{
    30     constructor(light){
    31         super();
    32         this.light = light
    33     }
    34     buttonWasPressed(){
    35         console.log('-->强光');
    36         this.light.setState(this.light.strongLightState)
    37     }
    38 }
    39 
    40 class  Light{
    41     constructor(){
    42         this.strongLightState = new StrongLightState(this);
    43         this.offLightState = new OffLightState(this);
    44         this.weakLightState = new WeakLightState(this);
    45         this.currState = this.offLightState; // 设置当前状态
    46 
    47         let button = document.createElement( 'button' );
    48         button.innerHTML = '开关';
    49         this.button = document.body.appendChild( button );
    50         this.button.onclick = ()=>{
    51             this.currState.buttonWasPressed();
    52         }
    53     }
    54 
    55     setState(newState){
    56         this.currState = newState
    57     }
    58 }

     //  状态模式----闭包版本

     1 var delegate = function (client, delegation) {
     2     return {
     3         buttonWasPressed: function () { // 将客户的操作委托给 delegation 对象
     4             return delegation.buttonWasPressed.apply(client, arguments);
     5         }
     6     }
     7 };
     8 var FSM = {
     9     off: {
    10         buttonWasPressed: function () {
    11             console.log('关灯');
    12             this.button.innerHTML = '下一次按我是开灯';
    13             this.currState = this.onState;
    14         }
    15     },
    16     on: {
    17         buttonWasPressed: function () {
    18             console.log('开灯');
    19             this.button.innerHTML = '下一次按我是关灯';
    20             this.currState = this.offState;
    21         }
    22     }
    23 };
    24 var Light = function () {
    25     this.offState = delegate(this, FSM.off);
    26     this.onState = delegate(this, FSM.on);
    27     this.currState = this.offState; // 设置初始状态为关闭状态
    28     this.button = null;
    29 };
    30 Light.prototype.init = function () {
    31     var button = document.createElement('button'),
    32         self = this;
    33     button.innerHTML = '已关灯';
    34     this.button = document.body.appendChild(button);
    35     this.button.onclick = function () {
    36         self.currState.buttonWasPressed();
    37 
    38     }
    39 
    40 };
    41 
    42 var light = new Light();
    43 light.init();

    //文件上传下载 初级版本

      1 /**
      2  * Created by shangkuikui on 2017/5/8.
      3  */
      4 
      5 var plugin = (function () {
      6     var plugin = document.createElement('embed');
      7     plugin.style.display = 'none';
      8     plugin.type = 'application/txftn-webkit';
      9     plugin.sign = function () {
     10         console.log('开始文件扫描');
     11     }
     12     plugin.pause = function () {
     13         console.log('暂停文件上传');
     14     };
     15     plugin.uploading = function () {
     16         console.log('开始文件上传');
     17     };
     18     plugin.del = function () {
     19         console.log('删除文件上传');
     20     }
     21     plugin.done = function () {
     22         console.log('文件上传完成');
     23     }
     24     document.body.appendChild(plugin);
     25     return plugin;
     26 })();
     27 
     28 class Upload {
     29     constructor(fileName) {
     30         this.plugin = plugin;
     31         this.fileName = fileName;
     32         this.state = 'sign'; // 设置初始状态为 waiting
     33         var that = this;
     34         this.dom = document.createElement('div');
     35         this.dom.innerHTML =
     36             '<span>文件名称:' + this.fileName + '</span>
     37              <button data-action="button1">扫描中</button>
     38               <button data-action="button2">删除</button>';
     39         document.body.appendChild(this.dom);
     40         this.button1 = this.dom.querySelector( '[data-action="button1"]' ); // 第一个按钮
     41         this.button2 = this.dom.querySelector( '[data-action="button2"]' ); // 第二个按钮
     42         this.bindEvent();
     43     }
     44     bindEvent(){
     45         var self = this;
     46         this.button1.onclick = function(){
     47             if ( self.state === 'sign' ){ // 扫描状态下,任何操作无效
     48                 console.log( '扫描中,点击无效...' );
     49             }else if ( self.state === 'uploading' ){ // 上传中,点击切换到暂停
     50                 self.changeState( 'pause' );
     51             }else if ( self.state === 'pause' ){ // 暂停中,点击切换到上传中
     52                 self.changeState( 'uploading' );
     53             }else if ( self.state === 'done' ){
     54                 console.log( '文件已完成上传, 点击无效' );
     55             }else if ( self.state === 'error' ){
     56                 console.log( '文件上传失败, 点击无效' );
     57             }
     58         };
     59         this.button2.onclick = function(){
     60             if ( self.state === 'done' || self.state === 'error'
     61                 || self.state === 'pause' ){
     62             // 上传完成、上传失败和暂停状态下可以删除
     63                 self.changeState( 'del' );
     64             }else if ( self.state === 'sign' ){
     65                 console.log( '文件正在扫描中,不能删除' );
     66             }else if ( self.state === 'uploading' ){
     67                 console.log( '文件正在上传中,不能删除' );
     68             }
     69         };
     70     }
     71     changeState(state){
     72         switch( state ){
     73             case 'sign':
     74                 this.plugin.sign();
     75                 this.button1.innerHTML = '扫描中,任何操作无效';
     76                 break;
     77             case 'uploading':
     78                 this.plugin.uploading();
     79                 this.button1.innerHTML = '正在上传,点击暂停';
     80                 break;
     81             case 'pause':
     82                 this.plugin.pause();
     83                 this.button1.innerHTML = '已暂停,点击继续上传';
     84                 break;
     85             case 'done':
     86                 this.plugin.done();
     87                 this.button1.innerHTML = '上传完成';
     88                 break;
     89             case 'error':
     90                 this.button1.innerHTML = '上传失败';
     91                 break;
     92             case 'del':
     93                 this.plugin.del();
     94                 this.dom.parentNode.removeChild( this.dom );
     95                 console.log( '删除完成' );
     96                 break;
     97         }
     98         this.state = state;
     99     }
    100 }
    101 
    102 window.external.upload = function (state) {
    103     uploadObj.changeState( state ); // 可能为 sign、 uploading、 done、 error
    104 };
    105 var uploadObj = new Upload( 'JavaScript 设计模式与开发实践' );
    106 window.external.upload( 'sign' ); // 文件开始扫描
    107 setTimeout(function(){
    108     window.external.upload( 'uploading' ); // 1 秒后开始上传
    109 }, 1000 );
    110 setTimeout(function(){
    111     window.external.upload( 'done' ); // 5 秒后上传完成
    112 }, 5000 );

    //享元模式版本

      1 /**
      2  * Created by shangkuikui on 2017/5/8.
      3  */
      4 let plugin = (function () {
      5     let plugin = document.createElement('embed');
      6     plugin.style.display = 'none';
      7     plugin.type = 'application/txftn-webkit';
      8     plugin.sign = function () {
      9         console.log('开始文件扫描');
     10     }
     11     plugin.pause = function () {
     12         console.log('暂停文件上传');
     13     };
     14     plugin.uploading = function () {
     15         console.log('开始文件上传');
     16     };
     17     plugin.del = function () {
     18         console.log('删除文件上传');
     19     }
     20     plugin.done = function () {
     21         console.log('文件上传完成');
     22     }
     23     document.body.appendChild(plugin);
     24     return plugin;
     25 })();
     26 window.external.upload = function (state) {
     27     uploadObj[state](); // 此处可以看到策略模式的影子
     28 };
     29 
     30 var StateFactory = (function () {
     31     var State = function () {
     32     };
     33     State.prototype.clickHandler1 = function () {
     34         throw new Error('子类必须重写父类的 clickHandler1 方法');
     35     }
     36     State.prototype.clickHandler2 = function () {
     37         throw new Error('子类必须重写父类的 clickHandler2 方法');
     38     }
     39     return function (param) {
     40         var F = function (uploadObj) {
     41             this.uploadObj = uploadObj;
     42         };
     43         F.prototype = new State();
     44         for (var i in param) {
     45             F.prototype[i] = param[i];
     46         }
     47         return F;
     48     }
     49 })();
     50 var SignState = StateFactory({
     51     clickHandler1: function () {
     52         console.log('扫描中,点击无效...');
     53     },
     54     clickHandler2: function () {
     55         console.log('文件正在上传中,不能删除');
     56     }
     57 });
     58 var UploadingState = StateFactory({
     59     clickHandler1: function(){
     60         this.uploadObj.pause();
     61     },
     62     clickHandler2: function(){
     63         console.log( '文件正在上传中,不能删除' );
     64     }
     65 });
     66 var PauseState = StateFactory({
     67     clickHandler1: function(){
     68         this.uploadObj.uploading();
     69     },
     70     clickHandler2: function(){
     71         this.uploadObj.del();
     72     }
     73 });
     74 var DoneState = StateFactory({
     75     clickHandler1: function(){
     76         console.log( '文件已完成上传, 点击无效' );
     77     },
     78     clickHandler2: function(){
     79         this.uploadObj.del();
     80     }
     81 });
     82 var ErrorState = StateFactory({
     83     clickHandler1: function(){
     84         console.log( '文件上传失败, 点击无效' );
     85     },
     86     clickHandler2: function(){
     87         this.uploadObj.del();
     88     }
     89 });
     90 
     91 
     92 
     93 class Upload {
     94     constructor(fileName) {
     95         this.plugin = plugin;
     96         this.fileName = fileName;
     97 
     98         //此处是享元模式的优化点
     99         this.signState = new SignState(this);
    100         this.pauseState = new PauseState(this);
    101         this.uploadingState = new UploadingState(this);
    102         this.doneState = new DoneState(this);
    103         this.errorState = new ErrorState(this);
    104         this.currState = this.signState; // 设置当前状态
    105 
    106         var that = this;
    107         this.dom = document.createElement('div');
    108         this.dom.innerHTML =
    109             '<span>文件名称:' + this.fileName + '</span>
    110              <button data-action="button1">扫描中</button>
    111               <button data-action="button2">删除</button>';
    112         document.body.appendChild(this.dom);
    113         this.button1 = this.dom.querySelector('[data-action="button1"]'); // 第一个按钮
    114         this.button2 = this.dom.querySelector('[data-action="button2"]'); // 第二个按钮
    115         this.bindEvent();
    116     }
    117 
    118     bindEvent() {
    119         var self = this;
    120         this.button1.onclick = () => {
    121             this.currState.clickHandler1();//状态模式能够使用的关键地方,就是每一个状态对象都有一个相同方法,才可以成功实现委托
    122         }
    123         this.button2.onclick = () => {
    124             this.currState.clickHandler2();
    125         }
    126     }
    127 
    128     setState(newState) {
    129         this.currState = newState
    130     }
    131 
    132     sign() {
    133         this.plugin.sign();
    134         this.currState = this.signState;
    135     }
    136 
    137     uploading() {
    138         this.button1.innerHTML = '正在上传,点击暂停';
    139         this.plugin.uploading();
    140         this.currState = this.uploadingState;
    141     }
    142 
    143     pause() {
    144         this.button1.innerHTML = '已暂停,点击继续上传';
    145         this.plugin.pause();
    146         this.currState = this.pauseState;
    147     }
    148 
    149     done() {
    150         this.button1.innerHTML = '上传完成';
    151         this.plugin.done();
    152         this.currState = this.doneState;
    153     };
    154 
    155     error() {
    156         this.button1.innerHTML = '上传失败';
    157         this.currState = this.errorState;
    158     };
    159 
    160     del() {
    161         this.plugin.del();
    162         this.dom.parentNode.removeChild(this.dom);
    163     };
    164 }
    165 
    166 var uploadObj = new Upload('JavaScript 设计模式与开发实践');
    167 setTimeout(function () {
    168     window.external.upload('uploading');
    169 }, 1000);
    170 setTimeout(function () {
    171     window.external.upload('done');
    172 }, 5000);

     //最终版本加入享元模式的 状态模式版本

    /**
     * Created by shangkuikui on 2017/5/10.
     */
    let plugin = (function () {
        let plugin = document.createElement('embed');
        plugin.style.display = 'none';
        plugin.type = 'application/txftn-webkit';
        plugin.sign = function () {
            console.log('开始文件扫描');
        }
        plugin.pause = function () {
            console.log('暂停文件上传');
        };
        plugin.uploading = function () {
            console.log('开始文件上传');
        };
        plugin.del = function () {
            console.log('删除文件上传');
        }
        plugin.done = function () {
            console.log('文件上传完成');
        }
        document.body.appendChild(plugin);
        return plugin;
    })();
    
    
    var StateFactory = (function () {
        var State = function () {
        };
        State.prototype.clickHandler1 = function () {
            throw new Error('子类必须重写父类的 clickHandler1 方法');
        }
        State.prototype.clickHandler2 = function () {
            throw new Error('子类必须重写父类的 clickHandler2 方法');
        }
        return function (param) {
            var F = function (uploadObj) {
                this.uploadObj = uploadObj;
            };
            F.prototype = new State();
            for (var i in param) {
                F.prototype[i] = param[i];
            }
            return F;
        }
    })();
    var SignState = StateFactory({
        clickHandler1: function () {
            console.log('扫描中,点击无效...');
        },
        clickHandler2: function () {
            console.log('文件正在上传中,不能删除');
        }
    });
    var UploadingState = StateFactory({
        clickHandler1: function () {
            this.uploadObj.pause();
        },
        clickHandler2: function () {
            console.log('文件正在上传中,不能删除');
        }
    });
    var PauseState = StateFactory({
        clickHandler1: function () {
            this.uploadObj.uploading();
        },
        clickHandler2: function () {
            this.uploadObj.del();
        }
    });
    var DoneState = StateFactory({
        clickHandler1: function () {
            console.log('文件已完成上传, 点击无效');
        },
        clickHandler2: function () {
            this.uploadObj.del();
        }
    });
    var ErrorState = StateFactory({
        clickHandler1: function () {
            console.log('文件上传失败, 点击无效');
        },
        clickHandler2: function () {
            this.uploadObj.del();
        }
    });
    let UploadFactory = (function () {
        let upload;
        return {
            create: function () {
                if (upload) {
                    return upload;
                }
                return upload = new Upload();
            }
        }
    })();
    
    let UploadManager = (function () {
        let outerstate = {};
        return {
            add(id, fileName){
                let uploadObj = UploadFactory.create();
                let dom = document.createElement('div');
                dom.innerHTML =
                    '<span>文件名称:' + fileName + '</span>
                 <button data-action="button1">扫描中</button>
                  <button data-action="button2">删除</button>';
                document.body.appendChild(dom);
                let button1 = dom.querySelector('[data-action="button1"]'); // 第一个按钮
                let button2 = dom.querySelector('[data-action="button2"]'); // 第二个按钮
                button1.onclick = function () {
                    uploadObj.clickhandler1(id);
                }
                button2.onclick = function () {
                    uploadObj.clickhandler2(id);
                }
    
                outerstate[id] = {
                    fileName: fileName,
                    dom: dom,
                    button1: button1,
                    button2: button2
                };
                return uploadObj
            },
            setExternalState: function (id, flyWeightObj) {
                let uploadData = outerstate[id];
                for (let i in uploadData) {
                    flyWeightObj[i] = uploadData[i];
                }
            }
        }
    })()
    
    class Upload {
        constructor() {
            //this.fileName = fileName;
            //此处是享元模式的优化点
            this.plugin = plugin;
            this.signState = new SignState(this);
            this.pauseState = new PauseState(this);
            this.uploadingState = new UploadingState(this);
            this.doneState = new DoneState(this);
            this.errorState = new ErrorState(this);
            this.currState = this.signState; // 设置当前状态   此处有问题 因为当上传多个文件时候 currentstate 不应该共享,而是每一个文件有自己的currentstate
        }
    
        clickhandler1(id) {
            UploadManager.setExternalState(id, this);
            this.currState.clickHandler1();
        }
    
        clickhandler2(id) {
            UploadManager.setExternalState(id, this);
            this.currState.clickHandler2();
        }
    
        setState(newState) {
            this.currState = newState
        }
    
        sign() {
            this.plugin.sign();
            this.currState = this.signState;
        }
    
        uploading() {
            this.button1.innerHTML = '正在上传,点击暂停';
            this.plugin.uploading();
            this.currState = this.uploadingState;
        }
    
        pause() {
            this.button1.innerHTML = '已暂停,点击继续上传';
            this.plugin.pause();
            this.currState = this.pauseState;
        }
    
        done() {
            this.button1.innerHTML = '上传完成';
            this.plugin.done();
            this.currState = this.doneState;
        };
    
        error() {
            this.button1.innerHTML = '上传失败';
            this.currState = this.errorState;
        };
    
        del() {
            this.plugin.del();
            this.dom.parentNode.removeChild(this.dom);
        };
    }
    
    /*var uploadObj = UploadManager.add(0, 'JavaScript 设计模式与开发实践');
    window.external.upload = function (state) {
        uploadObj[state](); // 此处可以看到策略模式的影子
    };
    setTimeout(function () {
        UploadManager.setExternalState(0, uploadObj);
        window.external.upload('uploading');
    }, 1000);
    setTimeout(function () {
        UploadManager.setExternalState(0, uploadObj);
        window.external.upload('done');
    }, 5000);*/
    
    //test
    let uploadObj;
    window.external.upload = function (state) {
        uploadObj[state](); // 此处可以看到策略模式的影子
    };
    
    let books = ['JavaScript 设计模式与开发实践','活着','母猪的产后处理','颈椎病治疗大全'];
    books.forEach(function (item,index) {
        uploadObj = UploadManager.add(index, item);
        setTimeout(function () {
            UploadManager.setExternalState(index, uploadObj);
            window.external.upload('uploading');
        }, 1000*(index+1));
        setTimeout(function () {
            UploadManager.setExternalState(index, uploadObj);
            window.external.upload('done');
        }, 3000*(index+1));
    })
    //上面代码有问题 下面是正解



    1
    /** 2 * Created by shangkuikui on 2017/5/10. 3 */ 4 let plugin = (function () { 5 let plugin = document.createElement('embed'); 6 plugin.style.display = 'none'; 7 plugin.type = 'application/txftn-webkit'; 8 plugin.sign = function (id) { 9 console.log('开始文件扫描'); 10 } 11 plugin.pause = function (id) { 12 console.log(id+'号暂停文件上传'); 13 }; 14 plugin.uploading = function (id) { 15 console.log(id+'开始文件上传'); 16 }; 17 plugin.del = function (id) { 18 console.log('删除文件上传'); 19 } 20 plugin.done = function (id) { 21 console.log('文件上传完成'); 22 } 23 document.body.appendChild(plugin); 24 return plugin; 25 })(); 26 27 28 var StateFactory = (function () { 29 var State = function () { 30 }; 31 State.prototype.clickHandler1 = function () { 32 throw new Error('子类必须重写父类的 clickHandler1 方法'); 33 } 34 State.prototype.clickHandler2 = function () { 35 throw new Error('子类必须重写父类的 clickHandler2 方法'); 36 } 37 return function (param) { 38 var F = function (uploadObj) { 39 this.uploadObj = uploadObj; 40 }; 41 F.prototype = new State(); 42 for (var i in param) { 43 F.prototype[i] = param[i]; 44 } 45 return F; 46 } 47 })(); 48 var SignState = StateFactory({ 49 clickHandler1: function (id) { 50 console.log('扫描中,点击无效...'); 51 }, 52 clickHandler2: function (id) { 53 console.log('文件正在上传中,不能删除'); 54 } 55 }); 56 var UploadingState = StateFactory({ 57 clickHandler1: function (id) { 58 this.uploadObj.pause(id); 59 }, 60 clickHandler2: function (id) { 61 console.log('文件正在上传中,不能删除'); 62 } 63 }); 64 var PauseState = StateFactory({ 65 clickHandler1: function (id) { 66 this.uploadObj.uploading(id); 67 }, 68 clickHandler2: function (id) { 69 this.uploadObj.del(id); 70 } 71 }); 72 var DoneState = StateFactory({ 73 clickHandler1: function (id) { 74 console.log('文件已完成上传, 点击无效'); 75 }, 76 clickHandler2: function (id) { 77 this.uploadObj.del(id); 78 } 79 }); 80 var ErrorState = StateFactory({ 81 clickHandler1: function (id) { 82 console.log('文件上传失败, 点击无效'); 83 }, 84 clickHandler2: function (id) { 85 this.uploadObj.del(id); 86 } 87 }); 88 89 let UploadFactory = (function () { 90 let upload; 91 return { 92 create: function () { 93 if (upload) { 94 return upload; 95 } 96 return upload = new Upload(); 97 } 98 } 99 })(); 100 101 let UploadManager = (function () { 102 let outerstate = {}; 103 return { 104 add(id, fileName){ 105 let uploadObj = UploadFactory.create(); 106 let dom = document.createElement('div'); 107 dom.innerHTML = 108 '<span>文件名称:' + fileName + '</span> 109 <button data-action="button1">扫描中</button> 110 <button data-action="button2">删除</button>'; 111 document.body.appendChild(dom); 112 let button1 = dom.querySelector('[data-action="button1"]'); // 第一个按钮 113 let button2 = dom.querySelector('[data-action="button2"]'); // 第二个按钮 114 button1.onclick = function () { 115 uploadObj.clickhandler1(id); 116 } 117 button2.onclick = function () { 118 uploadObj.clickhandler2(id); 119 } 120 121 outerstate[id] = { 122 fileName: fileName, 123 dom: dom, 124 button1: button1, 125 button2: button2, 126 currState : uploadObj.signState // 设置当前状态 127 }; 128 return uploadObj 129 }, 130 setExternalState: function (id, flyWeightObj) { 131 let uploadData = outerstate[id]; 132 for (let i in uploadData) { 133 flyWeightObj[i] = uploadData[i]; 134 } 135 }, 136 changeExternalState:function (id, objstate) { 137 let uploadData = outerstate[id]; 138 uploadData.currState = objstate 139 } 140 } 141 })() 142 143 class Upload { 144 constructor() { 145 //this.fileName = fileName; 146 //此处是享元模式的优化点 147 this.plugin = plugin; 148 this.signState = new SignState(this); 149 this.pauseState = new PauseState(this); 150 this.uploadingState = new UploadingState(this); 151 this.doneState = new DoneState(this); 152 this.errorState = new ErrorState(this); 153 154 } 155 156 clickhandler1(id) { 157 UploadManager.setExternalState(id, this); 158 this.currState.clickHandler1(id); 159 } 160 161 clickhandler2(id) { 162 UploadManager.setExternalState(id, this); 163 this.currState.clickHandler2(id); 164 } 165 166 setState(newState) { 167 this.currState = newState 168 } 169 170 sign(id) { 171 this.plugin.sign(id); 172 this.currState = this.signState; 173 } 174 175 uploading(id) { 176 this.button1.innerHTML = '正在上传,点击暂停'; 177 this.plugin.uploading(id); 178 this.currState = this.uploadingState; 179 } 180 181 pause(id) { 182 this.button1.innerHTML = '已暂停,点击继续上传'; 183 this.plugin.pause(id); 184 this.currState = this.pauseState; 185 } 186 187 done(id) { 188 this.button1.innerHTML = '上传完成'; 189 this.plugin.done(id); 190 this.currState = this.doneState; 191 }; 192 193 error(id) { 194 this.button1.innerHTML = '上传失败'; 195 this.currState = this.errorState; 196 }; 197 198 del(id) { 199 this.plugin.del(id); 200 this.dom.parentNode.removeChild(this.dom); 201 }; 202 } 203 204 /*var uploadObj = UploadManager.add(0, 'JavaScript 设计模式与开发实践'); 205 window.external.upload = function (state) { 206 uploadObj[state](); // 此处可以看到策略模式的影子 207 }; 208 setTimeout(function () { 209 UploadManager.setExternalState(0, uploadObj); 210 window.external.upload('uploading'); 211 }, 1000); 212 setTimeout(function () { 213 UploadManager.setExternalState(0, uploadObj); 214 window.external.upload('done'); 215 }, 5000);*/ 216 217 //test 218 let uploadObj; 219 220 window.external.upload = function (state) { 221 uploadObj[state](); // 此处可以看到策略模式的影子 222 }; 223 224 let books = ['JavaScript 设计模式与开发实践','活着','母猪的产后处理','颈椎病治疗大全']; 225 books.forEach(function (item,index) { 226 uploadObj = UploadManager.add(index, item); 227 let timer1 = setTimeout(function () { 228 UploadManager.changeExternalState(index,uploadObj.uploadingState); 229 UploadManager.setExternalState(index, uploadObj); 230 window.external.upload('uploading'); 231 }, 1000*(index+1)); 232 let timer2 = setTimeout(function () { 233 UploadManager.changeExternalState(index,uploadObj.doneState); 234 UploadManager.setExternalState(index, uploadObj); 235 window.external.upload('done'); 236 }, 3000*(index+1)); 237 })

    最后补一张 我(丑)精(陋)心绘(瞎)制(画)的示意图

     

  • 相关阅读:
    CentOS75 安装 telnet 进行使用.
    Windows 创建计划任务 实现自动同步文件.
    qemu-img.exe 工具 简介
    中建项目环境迁移说明
    服务器内存最大大小限制
    bzip2 以及 tar 压缩/解压缩/.打包等工具软件
    Ubuntu18.04 安装后的简单实用设置[未完成]
    oracle 启动监听报错TNS-12547: TNS:lost contact
    Linux审计sudo
    OPENVAS运行
  • 原文地址:https://www.cnblogs.com/WhiteHorseIsNotHorse/p/6830019.html
Copyright © 2011-2022 走看看