本身封裝訂閱發佈庫

//基於es6本身封裝發佈訂閱庫 jQ中的發佈訂閱沒有去重的功能
let _subscribe = function(){
    //SUB :發佈訂閱類
    class Sub{
        constructor(){
            //建立一個事件池,用來存儲後期須要執行的方法
            this.$pond = [];
        }
        //給事件池追加方法(作重複處理)
        add(func){
            let flag = this.$pond.some(item=>{
                return item === func;
            });
            !flag ? this.$pond.push(func) : null;
        }
        //從事件池中移除方法
        remove(func){
            let $pond = this.$pond;
            for(let i = 0;i < $pond.length; i++){
                let item  = $pond[i];
                if(item === func){
                    //移除(順序不變的狀況下基本上只能用splice了,可是不能這樣寫,這樣寫會致使數組塌陷問題,咱們不能真正移除,只能把當前項賦值爲null.
                    // $pond.splice(i,1);
                    $pond[i] = null;
                    break;
                }
            }
        }
        //通知事件池中的方法,按照順序執行
        fire(...args){
            let $pond =this.$pond;
            for(let i = 0; i< $pond.length;i++){
                let item = $pond[i];
                if(typeof item !== 'function'){
                    //此時再刪除
                    $pond.splice(i,1);
                    i--;
                    continue;
                }
                item.call(this, ...args)
            }
        }
    }
    //暴露給外面用
    return function subscribe(){
        return new Sub();
    }
}();

//使用 let s1 = _subscribe();
//事件池中移出事件致使的數組塌陷問題:fire的時候通知事件執行時,拿循環的索引i去對應數組的下標,當有事件被移除時,數組發生變化,可是去對應的索引i繼續去對應,會致使事件中某幾項被跳過.
//解決:移除用僞裝移除,把當前項改爲null,這樣索引仍是不變.真正移除在fire的時候去進行,此時fire時需檢查執行的是否爲function
相關文章
相關標籤/搜索