釋出-訂閱方式實現非同步併發

風雪中的兔子發表於2019-03-21

通過釋出/訂閱者模式實現非同步併發

非同步意味著我們期望得到的結果不會像同步那樣順序或序列拿到結果,什麼時候得到結果是未知的 釋出訂-閱者模式實現非同步併發非常簡單,它的關鍵在於: 每次程式呼叫都會去執行(即釋出)已經被訂閱過的所有方法,在訂閱的方法中去判斷是否滿足條件,滿足條件則執行接下來的其它操作..


實現流程

  1. 定義物件, 該物件具有訂閱方法、釋出方法、用於存放訂閱方法的集合
let obj = {
	// 用於存放所有訂閱的方法,在每次釋出的時候會挨個的執行一次
	funcArray: [],
	// 用於訂閱,執行它會把要訂閱的方法存放到方法集合中
	on (func){
		this.funcArray.push(func);
	},
	// 釋出,該方法會把訂閱的方法挨個的執行一次,執行的過程中不斷地去判斷是否滿足某個條件
	fire (){
		this.funcArray.forEach( func => func.apply(this, arguments));
	}
}; 

複製程式碼
  1. 定義用於監測的物件
// 假定非同步全部執行完成後期望得到的結果是: myInfo = {age: 18, sex: 'man'}; ,根據該條件定義物件
let myInfo = {};

// 判斷是否滿足的條件是: myInfo物件 既有age屬性,又有sex屬性;
let keys = Object.keys(myInfo);
if(keys.includes('age') && keys.includes('sex')){ // something.....}

複製程式碼
  1. 訂閱方法
obj.on((key, data) => {
	myInfo[key] = data;
	let keys = Object.keys(myInfo);
	if(keys.includes('age') && keys.includes('sex')){
		console.log(myInfo);
	}
});
複製程式碼
  1. 非同步執行,執行的回撥裡面進行釋出
setTimeout(()=>{
	obj.fire('age', 18);
}, 2000);

setTimeout(()=>{
	obj.fire('sex', 'man');
}, 3000);
複製程式碼
  1. 簡單化
	// 訂閱的過程,實質上就是把要執行的方法存起來
	let fn1 = function(){ console.log('fn1'); }
	let fn2 = function(){ console.log('fn2'); }
	let arr = [fn1, fn2];
複製程式碼
	// 釋出實質上就是把訂閱的方法挨個的執行
	arr.forEach(fn=>fn());  // 釋出
複製程式碼
  1. 完整程式碼 可拷貝直接執行
	let obj = {
		// 用於存放所有訂閱的方法,在每次釋出的時候會挨個的執行一次
		funcArray: [],
		// 用於訂閱,執行它會把要訂閱的方法存放到方法集合中
		on (func){
			this.funcArray.push(func);
		},
		// 釋出,該方法會把訂閱的方法挨個的執行一次,執行的過程中不斷地去判斷是否滿足某個條件
		fire (){
			this.funcArray.forEach( func => func.apply(this, arguments));
		}
	}; 
	
	
	let myInfo = {};
	
	obj.on((key, data) => {
		myInfo[key] = data;
		let keys = Object.keys(myInfo);
		if(keys.includes('age') && keys.includes('sex')){
			console.log('Success! coding...');
		}
	});
	
	setTimeout(()=>{
		obj.fire('age', 18);
	}, 2000);
	
	setTimeout(()=>{
		obj.fire('sex', 'man');
	}, 3000);
複製程式碼

相關文章