发布订阅模式可以用公众号来进行比喻,好多账号关注了一个公众号就相当于订阅,当公众号有信息需要发布时,就会依次通知订阅了公众号的账号。 可以用js来模拟这个操作,主要方法有
-
$on 订阅
-
$emit 通知发布
-
$off 取消订阅
-
$once 只执行一次
-
首先定义对象用来存储方法
let EventObj = {
}
- 对象上添加$on方法,用来订阅事件
参数是 fnName:订阅的事件名 fn:事件绑定的方法
我们使用数组来保存订阅的事件列如 fnName:[fn1,fn2,fn3.....]。首先判断是否订阅了fnNmae,订阅了就向数组添加方法,没有订阅就先创建数组再添加方法。
EventObj.$on = function (fnName, fn) {
if (EventObj[fnName]) {
EventObj[fnName].push(fn)
} else {
EventObj[fnName] = []
EventObj[fnName].push(fn)
}
}
- 对象上添加$emit方法,用来发布通知订阅事件
参数是 fnName:订阅的事件名 args:事件的参数
判断EventObj里面是否有订阅的事件,也就是EventObj[fnName]这个数组是否有值,有的话就通知数组里面的方法依次执行。
EventObj.$emit = function (fnName, ...args) {
if (EventObj[fnName] && EventObj[fnName].length > 0) {
EventObj[fnName].forEach(element => {
element(args)
});
} else {
console.log('未订阅事件');
}
}
- 对象上添加$off方法,用来取消订阅事件
参数是 fnName:订阅的事件名
判断EventObj里面是否有订阅的事件,有的话,删除事件数组就行
EventObj.$off = function (fnName) {
if (EventObj[fnName]) {
delete EventObj[fnName]
} else {
console.log('未订阅事件off');
}
}
- 对象上添加$once方法,只执行一次订阅事件
参数是 fnName:订阅的事件名 fn:事件绑定的方法
只执行一次,所以我们可以在首次执行后,调用on方法进行订阅。
EventObj.$once = function (fnName, fn) {
let newFn = () => {
fn()
this.$off(fnName)
}
this.$on(fnName, newFn)
}
全部代码如下
let EventObj = {
}
EventObj.$on = function (fnName, fn) {
if (EventObj[fnName]) {
EventObj[fnName].push(fn)
} else {
EventObj[fnName] = []
EventObj[fnName].push(fn)
}
}
EventObj.$emit = function (fnName, ...args) {
if (EventObj[fnName] && EventObj[fnName].length > 0) {
EventObj[fnName].forEach(element => {
element(args)
});
} else {
console.log('未订阅事件');
}
}
EventObj.$once = function (fnName, fn) {
let newFn = () => {
fn()
this.$off(fnName)
}
this.$on(fnName, newFn)
}
EventObj.$off = function (fnName) {
if (EventObj[fnName]) {
delete EventObj[fnName]
} else {
console.log('未订阅事件off');
}
}
function addfun() {
console.log(555);
}
EventObj.$once('add', addfun)
EventObj.$emit('add')
EventObj.$emit('add')
有啥不对的,请大佬指点