状态模式全解析--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 })

 

 

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

 

 

posted @ 2017-05-09 12:21  _白马非马  阅读(428)  评论(0编辑  收藏  举报