之前写小程序,然后遇到个登录过期的问题,由于小程序页面只要是在栈中,就可以一直运行,所以,通过登录过期这个事件的发布,使所有订阅了这个消息的页面进行一些操作,可以省去一些麻烦
这里写了个简单可用的发布订阅,在项目里面使用也很简单,直接放在 globalData 里面供全局所有页面使用
// 发布订阅
class MyEvent {
constructor () {
this.events = {}
}
// 添加事件监听
on (type, fn) {
if (!this.events[type]) {
this.events[type] = []
}
this.events[type].push(fn)
}
// 触发事件 例:fire('click', 1)
fire () {
let [type, ...otherArgs] = [...arguments]
let fnArray = this.events[type]
if (!fnArray) return false
for (let i = 0; i< fnArray.length; i++) {
if (typeof fnArray[i] !== 'function') {
// 检测到当前项不是函数,删除并继续下一次循环
fnArray.splice(i, 1) // 这里删除已经移除的函数
i--
continue
}
fnArray[i](...otherArgs)
}
}
// 去除监听的某个回调 例:off('click', fn)
off () {
let [type, fn] = [...arguments]
console.log(type, fn)
let fnArray = this.events[type]
for (let i = 0; i < fnArray.length; i++) {
console.log(fnArray[i] === fn)
if (fnArray[i] === fn) {
// 删除回调函数
/*
不在这里使用 splice 去删除方法,是为了防止数组塌陷,
在 fire 执行过程中跳过了对某一个方法的执行,所以在这里假移除,
然后在 fire 方法那里再把它移除掉
*/
fnArray[i] = null
break
}
}
}
}
module.exports = MyEvent
发布消息:
app.globalData.ev.fire('logout') // 发送登出通知
订阅消息:
app.globalData.ev.on('logout', this.handleLogout)