Js實現訂閱釋出模式(讓你的程式碼寫得賊六)
阿新 • • 發佈:2019-02-02
簡單例子
var salesoffice = {}; //定義售樓處
salesoffice.clientList = []; //快取列表,存放訂閱者的回撥函式
salesoffice.listen = function (key,fn) { //增加訂閱者
if(!this.clientList[key]){
this.clientList[key] = [];
}
this.clientList[key].push(fn); //訂閱的訊息新增進快取列表
};
salesoffice.trigger = function () { //釋出訊息
var key = Array.prototype.shift.call(arguments); //取出訊息型別
fns = this.clientList[key];
if(!fns || fns.length ===0 ){ //如果沒有訂閱改訊息,則返回
return false;
}
for (var i = 0,fn;fn=fns[i++];){
fn.apply(this,arguments); //arguments 是釋出訊息時帶上的引數
}
};
//測試例子
salesoffice.listen('squareMeter88',function (price) { //小明訂閱訊息
console.log("價格=" + price );
});
salesoffice.listen('squareMeter110',function (price) { //小紅訂閱訊息
console.log("價格=" + price );
});
salesoffice.trigger('squareMeter88',2000000);
salesoffice.trigger('squareMeter110' ,3000000);
通用實現
//通用實現
var event = {
clientList:[],
listen : function (key,fn) {
if(!this.clientList[ key ]){
this.clientList[ key ] = [];
}
this.clientList[key].push(fn);
},
trigger:function () {
var key = Array.prototype.shift.call(arguments),
fns = this.clientList[ key ];
if(!fns || fns.length===0){
return false;
}
for (var i=0,fn;fn = fns[i++];){
fn.apply(this,arguments);
}
}
};
//在定義一個instalEvent 函式,這個函式可以給所有的物件都動態安裝釋出訂閱模式
var installEvent = function (obj) {
for (var i in event){
obj[i] = event[i];
}
}
var salesOffices = {};
installEvent(salesOffices);
salesOffices.listen('squareMeter88',function (price) { //小明訂閱訊息
console.log("價格=" + price );
});
salesOffices.listen('squareMeter110',function (price) { //小紅訂閱訊息
console.log("價格=" + price );
});
salesOffices.trigger('squareMeter88',2000000);
salesOffices.trigger('squareMeter110',3000000);
//取消訂閱事件
event.remove = function (key,fn) {
var fns = this.clientList[ key ];
if( !fns ){ //如果key對應的訊息沒有被人訂閱,則直接返回
return false;
}
if( !fn ){ //如果傳入的具體的回撥函式,表示需要取消key對應訊息的所有訂閱
fns && (fns.length=0);
}else{
for (var l = fns.length - 1;l >=0;l--){
var _fn = fns[l];
if(_fn === fn){
fns.splice(l,1); //刪除訂閱者的回撥函式
}
}
}
}
var salesOffices = {};
installEvent(salesOffices);
salesOffices.listen('squareMeter88',fn1 = function (price) { //小明訂閱訊息
console.log("價格=" + price );
});
salesOffices.listen('squareMeter110',fn2 = function (price) { //小紅訂閱訊息
console.log("價格=" + price );
});
salesOffices.remove('squareMeter88',fn1); //刪除小明的訂閱
salesOffices.trigger('squareMeter110',2000000);
全域性的釋出–訂閱物件
//全域性的釋出--訂閱物件
var Event = (function () {
var clientList = {},
listen,
trigger,
remove;
listen = function (key,fn) {
if(!clientList[key]){
clientList[key]=[];
}
clientList[key].push(fn);
};
trigger = function () {
var key = Array.prototype.shift.call(arguments),
fns = clientList[key];
if(!fns || fns.length===0){
return false;
}
for (var i =0,fn;fn=fns[i++];){
fn.apply(this,arguments);
}
};
remove = function (key,fn) {
var fns = clientList[key];
if(!fns){
return false
}
if(!fn){
fns && (fns.length=0);
}else{
for (var l=fns.length-1;l>=0;l--){
var _fn = fns[l];
if(_fn===fn){
fns.splice(l,1);
}
}
}
};
return {
listen:listen,
trigger:trigger,
remove:remove,
}
})();
Event.listen('squareMeter88',function (price) {
console.log("價額="+price);
});
Event.trigger('squareMeter88',2000000);
最後想說:
最近才想著把自己這三年來學到的東西分享出來,技術是無邊界的,共享才是趨勢!下面是我的個人公眾號,喜歡的朋友可以關注一下哈。