实现一个发布订阅模式
基本方法
on():注册事件;也就是该模式中的发布;
emit():触发事件;该模式中的订阅;
once():注册只能触发一次的事件;触发后即被删除;
off():删除指定已注册事件;
优缺点
优点:
广泛应用于异步编程,可以代替传统的回调函数,只需要关注事件完成的时间点;
时间上解耦,对象间解耦;
(耦合:对象间的耦合度就是对象之间的依赖性,耦合度越高,维护成本就越高;
解耦:接触耦合关系)
缺点:
创建订阅者会消耗一定内存;
过度使用会导致代码难以维护;
代码
class EventEmitter{
constructor(){
//存放事件
this.cache = {}
}
// 注册事件
on(name,func){
const tasks = this.cache[name]
// 判断cache中是否有name事件的回调数组
if(tasks){
// 有则把func存进数组中
this.cache[name].push(func)
}else{
// 没有则创建一个数组,并把func放到其中
this.cache[name] = [func]
}
}
// 移除事件
off(name,func){
const tasks = this.cache[name]
if(tasks){
//查找cache的name事件的回调数组是否存在func,并返回索引值给index
const index = tasks.findIndex(item => item === func)
if(index >= 0){
//有则使用splice从index位置开始删除一个元素
this.cache[name].splice(index,1)
}
}
}
//触发事件
emit(name, ...args){
//浅拷贝到tasks
const tasks = this.cache[name].slice()
//判断一下是否存在
if(tasks){
//存在即循环tasks执行func,参数为传进的args
for(let func of tasks){
func(...args)
}
}
}
// 注册只能调用一次的事件
once(name,cb){
//定义一个方法func用于注册
//一旦被调用即执行callback函数和off函数删除事件
function func(...args){
cb(args)
this.off(name,func)
}
//注册事件,触发即调用
this.on(name,func)
}
}
该实现中用到的一些方法函数
slice
它返回的是一个新的数组对象,通过参数begin和end决定的对原数组的浅拷贝;
!!slice不会影响原数组!!
语法
arr.slice(begin,end)
begin(可选):起始索引值,从0开始;如果它为负数,则从倒是第几个元素开始,-1为倒数第一个;如果begin超过数组长度,则返回空数组;
end(可选):基本与begin相同;如果end不设定,则提到到结尾;如果end超过数组长度,同样提取到结尾;
返回值
返回一个新数组内含被提取元素
splice
通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。
!!splice方法会改变原数组!!。
语法
arr.splice(start,deleteCount,item...)
start:起始位置(索引值),与slice的begin相同;
deleteCount(可选):整数,表示要删除的数组元素个数;
item...:添加仅数组的元素,从start开始
返回值
返回一个由被删除的元素组成的数组,没有删除元素则返回空数组;
findIndex()
返回数组中满足提供条件的第一个元素的索引;若没有找到则返回-1;