發佈訂閱者模式以及vue中數據劫持 +結合發佈/訂閱模式

class Event {
	constructor(){
		this.events = {}
	}
	on(type, handler) {
		if(!this.events.hasOwnProperty(type)){
			this.events[type] = [];
		}
		this.events[type].push(handler)
    	        return this;
  	}
  	emit(type, ...args) {
	    for(let i = 0; i < this.events[type].length; i++) {
	       this.events[type][i].apply(this, args)
	    }
    	    return this;
  	}
  	off(type, handler){
  		if(!this.events.hasOwnProperty(type)){
  			throw new Error(`不存在${type}`)
  		}
  		const len = this.events[type].length
  		const eventHandler = this.events[type]
  		for(let i = 0; i < len; i++) {
  			if(eventHandler[i] == handler){
  				eventHandler.splice(i, 1)
  			}
  		}
  		return this;
  	}
  	once(type, handler){
		const on = (...args) => {
		  handler.apply(this, args)
	      this.off(type, on)
	    }
	    this.on(type, on)
    	    return this;
  	}
}

const event = new Event()
const a1 = function(data){
    console.log(1 + data);
}
// event.on('a', a1);
// event.emit('a', '我是第1次調用的參數');
// event.emit('a', '我是第2次調用的參數');  
event.once('b', a1);
event.emit('b', '一次');
event.emit('b', '兩次');



// vue中數據劫持結合發佈/訂閱模式
class Observer {
	constructor (value) {
	    this.value = value
	    this.dep = new Dep()
	    this.walk(value)
  	}
  	walk (obj) {
	    const keys = Object.keys(obj)
	    for (let i = 0; i < keys.length; i++) {
	      defineReactive(obj, keys[i],obj[keys[i]])
	    }
  	}
}


function defineReactive (obj, key, value){
    const dep = new Dep()

    Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter () {
    	console.log('get')
        dep.addSub({
        	update:()=>{
        		console.log('執行update')
        	}
        });
        return value
    },
    set: function reactiveSetter (newVal) {
      if (newVal === value || (newVal !== newVal && value !== value)) {
        return
      }
      console.log('set')
	  value = newVal;
	  dep.notify();
    }
  })

}


class Dep {
	constructor (valuey) {
     	this.subs = [];
	}
	addSub(sub){
         this.subs.push(sub);
    }
    notify(){
	     this.subs.forEach(function(sub){
	         sub.update();
	     });
    }
}
let obj ={a:1,b:2,c:3}

new Observer(obj)
obj.a
obj.a = 2複製代碼

對發佈訂閱者的通俗理解javascript

訂閱能夠理解爲寄存,發佈理解爲寄存的拿出調用,能夠寄存不少個,拿出不少個vue

觀察者模式主要是監聽java

相關文章
相關標籤/搜索