單例模式、發(fā)布訂閱、觀察者模式、迭代器模式

單例模式

  • 例如頁(yè)面有一個(gè)modal彈窗,無(wú)論哪個(gè)頁(yè)面每次打開(kāi)彈窗,其實(shí)都可以用同一個(gè)彈窗實(shí)例,不需要多次創(chuàng)建
  • 代碼實(shí)現(xiàn): 多次調(diào)用 aa 只打印一次 111, a == b 結(jié)果為true
var aa = (function () {
    var instance
    return function () {
        function Modal() {
            this.init();
        }
        Modal.prototype.init = function () {
            console.log('創(chuàng)建了modal')
        }
        if (!instance) { 
            console.log(111)  // 只打印一次 
            instance = new Modal();
        }
        return instance;
    }
})()
let a = aa()
let b = aa()
console.log(a, b , a == b)

觀察者模式和發(fā)布訂閱模式

  • 其實(shí)差不多,發(fā)布訂閱是觀察者模式的升級(jí)版
  • 發(fā)布訂閱比觀察者模式多了一個(gè)事件調(diào)度中心
  • 他們都是維持了對(duì)象/主題(subject)一對(duì)多依賴
  • 觀察者:維持的是對(duì)象以及依賴這個(gè)對(duì)象的多個(gè)事件的關(guān)系;
  • 發(fā)布訂閱:對(duì)象的不同主題以及依賴不同主題的多個(gè)事件的關(guān)系;

發(fā)布訂閱模式 - 賊簡(jiǎn)單實(shí)現(xiàn)

class Observable {
    private handlers: {
        [props: string]: fn[]
    } = {};
    subscribe(key: string, fun: fn) {
        if (!this.handlers[key]) this.handlers[key] = [];
        this.handlers[key].push(fun);
    }
    unSubscribe(key: string) { 
        delete this.handlers[key];
    }
    publish<K>(key: string, val: K) {
        let handlers = this.handlers[key] || [];
        handlers.forEach(item => {
            item(val)
        })
    }
 }
type fn = (v: any) => void;

// test
var observer = new Observable();
observer.subscribe('name', (val) => {
    console.log(`1 name is ${val}`)
})
observer.subscribe('name', (val) => {
    console.log(`2 name is ${val}`)
})
observer.subscribe('age', (val) => {
    console.log(`1 age is ${val}`)
})
observer.publish<string>('name', 'liuxinya')
observer.publish<number>('age', '18')

觀察者模式

  • handlers變成一個(gè)單一的數(shù)組
  • 訂閱直接往數(shù)組里面存事件
  • 發(fā)布直接遍歷數(shù)組里面的事件并傳入新值

Iterator Pattern

class IteratorFromArray {
    _array: any[]
    _cursor: number
    constructor(arr: any[]) {
        this._array = arr;
        this._cursor = 0;
    }
  
    next() {
        return this._cursor < this._array.length ?
        { value: this._array[this._cursor++], done: false } :
        { done: true };
    }
    map(callback: (v: any) => {done: boolean, value: any}) {
        let iterator = new IteratorFromArray(this._array)
        return {
            next: () => {
                const { done, value } = iterator.next()
                return {
                    done,
                    value: value ? callback(value) : undefined
                }
            }
        }  
    }
}
let test = new IteratorFromArray([1, 2, 3, 4])
console.log(test.next()) // {value: 1, done: false}
console.log(test.next())  //  {value: 2, done: false}
console.log(test.next()) //  {value: 3, done: false}

let testMap = test.map(value => value + 1)
console.log(testMap.next()) //{done: false, value: 2}
console.log(testMap.next()) // {done: false, value: 3}
console.log(testMap.next())
console.log(testMap.next())
console.log(testMap.next()) // {done: true, value: undefined}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 交朋友就要交那種即使變成老頭了也能互叫綽號(hào)的! 《初識(shí)RxJS》 背景 RP(Reactive Programmi...
    知行社閱讀 818評(píng)論 0 2
  • 準(zhǔn)備幫 GIT 申請(qǐng)吉尼斯世界紀(jì)錄,申請(qǐng)項(xiàng)目是 《人類能夠用命令行操作的最為復(fù)雜的軟件項(xiàng)目》。 《趣談 | Jav...
    知行社閱讀 1,076評(píng)論 0 4
  • 我早年都是用 VIM 寫(xiě)程序,也說(shuō)不上特別喜歡,主要是當(dāng)時(shí)還不知道怎么退出 VIM 《《深入理解ES6》教程學(xué)習(xí)筆...
    知行社閱讀 1,015評(píng)論 0 7
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 7,317評(píng)論 0 17
  • 當(dāng)一個(gè)軟件工程師宣稱他已經(jīng)完成了 90% 的工作,意思是他還需要相同的時(shí)間來(lái)完成剩下的 10% 的工作。 《用程序...
    知行社閱讀 933評(píng)論 0 4

友情鏈接更多精彩內(nèi)容