发布订阅就是将所有事件发到一个池子(数组)中,期间可以增减方法,要使用的时候统一依次执行,参数只能传相同的。期间要解决的问题是数组去重、数组塌陷。
let _subsribe = () => {
class sub {
constructor() {
this.pond = []
}
add(func) {
//去重
let flag = this.pond.some(item => item === func)
if (!flag && typeof (func) === 'function') this.pond.push(func)
}
remove(func) {
this.pond.forEach((item, index, arr) => {
if (item === func) {
//防止数组塌陷,用null占位
this.pond.splice(index, 1, null)
}
})
}
fire(...args) {
//解决数组塌陷问题
this.pond.forEach(item => item ? item.call(this, ...args) : null)
//去掉this.pond中的null
this.pond = this.pond.filter((item)=> item !== null)
}
}
//优化 不用每次都要new 直接调用方法就行了
return new sub()
}
//创建
let aa = _subsribe()
function fn1(e) {
console.log(1)
}
let fn2 = () => {
console.log(2)
}
let fn3 = () => {
console.log(3)
//这里小心有数组塌陷问题
aa.remove(fn2)
}
let fn4 = (ev) => {
console.log(4, ev)
}
aa.add(fn1)
aa.add(fn2)
aa.add(fn3)
aa.add(fn4)
//创建input元素
let o = document.createElement('input')
//将input插入到html中
let oo = document.querySelector('#root')
oo.insertBefore(o, null)
//可以传递onclick的默认event参数
o.onclick = function (ev) {
aa.fire(ev)
}