1. 程式人生 > >js的觀察者模式

js的觀察者模式

觀察者模式(釋出-訂閱模式):它定義物件間一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都將得到通知。由主體和觀察者組成,主體負責釋出事件,同時觀察者通過訂閱這些事件來觀察該主體。主體並不知道觀察者的任何事情,觀察者知道主體並能註冊事件的回撥函式。

訂閱者也稱為觀察者,而補觀察的物件稱為釋出者或主題。當發生了一個重要的事件時,釋出者將會通知(呼叫)所有訂閱者並且可能經常以事件物件的形式傳遞訊息。

假如我們正在開發一個商城網站,網站裡有header頭部、nav導航、訊息列表、購物車等模組。這幾個模組的渲染有一個共同的前提條件,就是必須先用ajax非同步請求獲取使用者的登入資訊。這是很正常的,比如使用者的名字和頭像要顯示在header模組裡,而這兩個欄位都來自使用者登入後返回的資訊。這個時候,我們就可以把這幾個模組的渲染事件都放到一個數組裡面,然後待登入成功之後再遍歷這個陣列並且呼叫每一個方法。

基本模式

<script type="text/javascript">
	var observer = {
		regist:function(eventName,callback){        //新增事件
			if(!this.obj){
				this.obj = {};
			}
			if(this.obj[eventName]){    //若方法已存在,新增到陣列,如果不存在,先建立一個數組然後在新增
				this.obj[eventName].push(callback);
			}else{
				this.obj[eventName] = [callback];
			}
		},
		emit:function(eventName){                //遍歷執行每一個方法
			if(this.obj[eventName]){
				for(var i = 0; i < this.obj[eventName].length; i++){
					this.obj[eventName][i]();
				}
			}
		},
		remove:function(eventName,callback){            //移除事件
			if(this.obj[eventName]){
				for(var i = 0; i < this.obj[eventName].length; i++){
					if(this.obj[eventName][i]==callback){
						this.obj[eventName].splice(i,1);
					}
				}
			}
		}
	}
</script>

貼一個觀察者模式面試題

var Event = {
				// 通過on介面監聽事件eventName
				// 如果事件eventName被觸發,則執行callback回撥函式
				on: function(eventName, callback) {
					
				},
				// 觸發事件 eventName
				emit: function(eventName) {
	
				}
			};
			
			
			// 測試1
			Event.on('test', function(result) {
				console.log(result);
			});
			Event.on('test', function() {
				console.log('test');
			});
			Event.emit('test', 'hello world'); // 輸出 'hello world' 和 'test'
		
			// 測試2
			var person1 = {};
			var person2 = {};
			
			Object.assign(person1, Event);

			Object.assign(person2, Event);
		
			person1.on('call1', function() {
				console.log('person1');
			});

			person2.on('call2', function() {
				console.log('person2');
			});
			
			person1.emit('call1'); // 輸出 'person1'
			person1.emit('call2'); // 沒有輸出
			person2.emit('call1'); // 沒有輸出
			person2.emit('call2'); // 輸出 'person2'

ps:轉自一個小姐姐的解析,很詳細。https://www.cnblogs.com/LuckyWinty/p/5796190.html