事件总线封装

此封装是对new Event()的一次练习,但能适用于大多数需要监听事件处理的情况,欢迎大家对于此封装进行 test and issue 

    // 事件总线封装
    function NqEventBus() {
      this.eventBus = {}
      NqEventBus.prototype.on = function(eventName,eventCallback) {
        if(typeof eventName !== 'string') {
          throw new TypeError('event name must be string type')
        }
        if(typeof eventCallback !== 'function') {
          throw new TypeError('event callback must be function type')
        }
        let eventInstance = this.eventBus[eventName]
        if(!eventInstance) {
          eventInstance = new Event(eventName)
          this.eventBus[eventName] = eventInstance
        }
        window.addEventListener(eventName, eventCallback)
      }
      NqEventBus.prototype.emit = function(eventName, ...payload) {
        if(typeof eventName !== 'string') {
          throw new TypeError('event name must be string type')
        }
        const eventInstance = this.eventBus[eventName]
        eventInstance['payload'] = payload
        if(eventInstance) {
          window.dispatchEvent(eventInstance)
        }
      }
      NqEventBus.prototype.off = function(eventName, eventCallback) {
        if(typeof eventName !== 'string') {
          throw new TypeError('event name must be string type')
        }
        if(typeof eventCallback !== 'function') {
          throw new TypeError('event callback must be function type')
        }
        if(eventCallback) {
          window.removeEventListener(eventName, eventCallback)
        }
      }
      NqEventBus.prototype.once = function(eventName, eventCallback) {
        if(typeof eventName !== 'string') {
          throw new TypeError('event name must be string type')
        }
        if(typeof eventCallback !== 'function') {
          throw new TypeError('event callback must be function type')
        }
        const tempCallback = (...payload) => {
          this.off(eventName, tempCallback)
          eventCallback(...payload)
        }
        this.on(eventName, tempCallback)
      }
    }

 使用方法:

let eventBus = new NqEventBus()

1. 注册处理函数

eventBus.on('事件名','事件函数')

2.触发事件处理函数

eventBus.emit('事件名','要传递的参数')

3.取消注册处理函数

eventBus.off('事件名','事件函数')

4. 也可以只执行一次监听

eventBus.once('事件名','事件函数')

 注意:传递的参数在事件对象下的payload属性下

<think>我们正在讨论ArkTS中的事件总线封装和模块间方法调用。根据引用内容,事件总线是一种用于模块间通信的解耦方案,而模块间方法调用涉及函数与模块的定义与调用。 事件总线封装示例:根据引用[1],我们可以创建一个事件总线类来管理事件的订阅和发布。下面是一个简单的事件总线封装示例: 模块间方法调用:根据引用[2],我们可以通过导出模块和导入模块来实现模块间的方法调用。例如,在一个模块中定义并导出一个函数,在另一个模块中导入并调用它。 由于用户要求示例,我们将分别展示事件总线封装和模块间方法调用的代码。 事件总线封装示例(参考引用[1]): 我们可以创建一个EventBus类,它包含订阅事件(on)、取消订阅(off)、触发事件(emit)等方法。 注意:在ArkTS中,我们通常使用TypeScript(或ArkTS)的类来实现。 模块间方法调用示例(参考引用[2]): 在ArkTS中,我们可以使用export导出模块中的函数,然后在另一个模块中使用import导入并使用。 下面分别给出两个示例: </think>基于您对ArkTS事件总线封装和模块间方法调用的需求,以下是详细解析及实现示例: --- ### 一、事件总线封装示例(解耦通信) 事件总线是一种发布-订阅模式,实现跨模块通信而不直接依赖引用。参考引用[1]的实现思路: ```typescript // EventBus.ets - 事件总线封装 export default class EventBus { private static events: Map<string, Array<Function>> = new Map() // 订阅事件 static on(eventName: string, callback: Function) { if (!this.events.has(eventName)) { this.events.set(eventName, []) } this.events.get(eventName)?.push(callback) } // 取消订阅 static off(eventName: string, callback?: Function) { const callbacks = this.events.get(eventName) if (!callbacks) return if (callback) { const index = callbacks.indexOf(callback) if (index > -1) callbacks.splice(index, 1) } else { this.events.delete(eventName) } } // 发布事件 static emit(eventName: string, ...args: any[]) { const callbacks = this.events.get(eventName) callbacks?.forEach(cb => cb(...args)) } } ``` **使用场景**: 1. **页面A发布事件**: ```typescript // PageA.ets import EventBus from './EventBus' Button('更新数据').onClick(() => { EventBus.emit('dataUpdate', { newData: "2023最新数据" }) }) ``` 2. **页面B订阅事件**: ```typescript // PageB.ets import EventBus from './EventBus' EventBus.on('dataUpdate', (data) => { console.log('收到更新:' + data.newData) }) ``` --- ### 二、模块间方法调用(直接调用) 通过模块导入/导出实现直接方法调用,参考引用[2][3]的模块化方案: #### 1. 定义可复用模块 ```typescript // MathUtils.ets - 工具模块 export function add(a: number, b: number): number { return a + b } export function formatString(str: string): string { return `Formatted_${str}` } ``` #### 2. 跨模块调用 ```typescript // BusinessModule.ets import { add, formatString } from './MathUtils' export function processData(value: number) { const sum = add(value, 100) // 调用其他模块方法 return formatString(`Result:${sum}`) // 链式调用 } ``` #### 3. 混合调用示例(ArkTS + Java) 参考引用[3]的混合编程模式: ```typescript // ArkTS模块 import javaModule from 'libs/javaModule' // Java模块 export function fetchData() { const raw = javaModule.getNativeData() // 调用Java方法 return processArkTSData(raw) // ArkTS处理 } ``` --- ### 三、两种方案对比 | **特性** | 事件总线 | 模块直接调用 | |------------------|----------------------------------|----------------------------| | 耦合度 | 低(完全解耦) | 高(需导入模块) | | 适用场景 | 跨页面/组件通信 | 工具类复用 | | 性能 | 需维护订阅列表 | 直接调用无额外开销 | | 典型应用 | 页面状态同步[^1] | 数据处理工具链[^2] | | 调试难度 | 较难(事件链路追踪) | 简单(直接调用栈) | --- ### 四、混合应用建议 1. **核心原则** - 解耦通信用事件总线(如全局状态更新) - 高频操作用模块调用(如数据处理工具) - 关键服务封装为单例(参考引用[4]的HttpService模式) 2. **代码组织规范** ```bash src/ ├── events/ # 事件总线 ├── modules/ # 功能模块 ├── utils/ # 工具类 └── services/ # 网络服务等单例 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值