@ng1005/chrome-extension-common
Version:
chrome扩展通用库--消息与storage
132 lines (118 loc) • 3.31 kB
text/typescript
import { isFunctionAsync } from "../utils/Utils";
/**
* 事件总线demo
*/
export class EventBusDemo {
_events:Map<string,Function|Array<Function>>;
constructor () {
this._events = new Map(); // 存储事件/回调键值对
}
/**
* on 监听
* @param type 消息类型
* @param fn 处理函数返回Promise<any>
*/
$on(type:string, fn:Function){
const handler = this._events.get(type)||[]; // 获取对应事件名称的函数清单
if (!handler) {
this._events.set(type, fn)
} else if (handler && typeof handler === 'function') {
// 如果handler是函数,说明当前只有一个监听者
// 再次添加监听者,需要改用 数组储存
this._events.set(type, [handler, fn]);
} else {
// 已有多个监听者,直接往数组里push函数即可
handler.push(fn);
this._events.set(type, handler);
}
return this
}
/**
* 提交事件
* @param type 消息类型
* @param args 参数
* @returns
*/
$emit(type:string, ...args:any):Promise<any>{
return new Promise(async(resolve,reject)=>{
let handler = this._events.get(type)
if(!handler)return Promise.resolve('');//无任何监听则退出
if (Array.isArray(handler)) {
// 是数组,说明有多个监听者,需要依次触发里边的函数
for (let i = 0; i < handler.length; ++i) {
if(isFunctionAsync(handler[i])){
let res=await handler[i].call(this, ...args)
resolve(res)
}else{
let res=handler[i].call(this, ...args)
resolve(res)
}
}
} else {
// 单个函数的情况直接触发即可
if(isFunctionAsync(handler)){
let res=await handler.call(this,...args)
resolve(res)
}else{
let res=handler.call(this,...args)
resolve(res)
}
}
return Promise.resolve('')
})
}
/**
* 移除监听
* @param type 类型
* @param fn 处理函数
*/
$off(type:string, fn:Function){
const handler = this._events.get(type)
if (handler && typeof handler === 'function') {
// 函数,说明只有一个监听者,直接删除就行
this._events.delete(type)
} else if(Array.isArray(handler)) {
handler.splice(handler.findIndex(e => e === fn), 1)
}
return this
}
/**
* 单次执行
* @param type 类型
* @param fn 处理函数
*/
$once(type:string, fn:Function){
let _self = this
function handler() {
_self.$off(type, handler)
fn.apply(null, arguments)
}
return this.$on(type, handler)
}
}
// 下面是 测试代码
function test1 (...params:any) {
console.log(11, params)
}
function test2 (...params:any) {
console.log(22, params)
}
function test3 (...params:any) {
console.log(33, params)
}
function test4 (...params:any) {
console.log(params)
console.log(33, params)
}
//测试用例
// let eb = new EventBusDemo()
// eb.on('event1', test1)
// eb.on('event1', test2)
// eb.on('event1', test3)
// eb.emit('event1', '第一次')
// eb.off('event1', test1)
// eb.emit('event1', ['第二次1', '第二次2'])
// eb.once('once', test4);
// eb.emit('once', '执行一次', 1, 2, 3)
const $bus=new EventBusDemo();
export default $bus