手写事件总线eventBus

本文介绍了如何从头构建一个自定义的事件总线(EventBus)类,用于处理事件订阅和发布。通过`on`方法订阅事件,`once`方法注册一次性事件,`emit`方法触发事件,以及`off`方法取消订阅。这个轻量级的事件管理工具对于模块间的通信非常实用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

手写事件总线eventBus

class EventBus {
	constructor() {
		this.tasks = {}; // 按事件名称创建任务队列
	}

	/**
	 * 注册事件(订阅)
	 * @param {String} type  事件名称
	 * @param {Function} fn  回调函数
	 */
	on(type, fn) {
		// 如果还没有注册过该事件,则创建对应事件的队列
		if (!this.tasks[type]) {
			this.tasks[type] = [];
		}
		// 将回调函数加入队列
		this.tasks[type].push(fn);
	}

	/**
	 * 注册一个只能执行一次的事件
	 * @params type[String] 事件类型
	 * @params fn[Function] 回调函数
	 */
	once(type, fn) {
		if (!this.tasks[type]) {
			this.tasks[type] = [];
		}

		const that = this;
		// 注意该函数必须是具名函数,因为需要删除,但该名称只在函数内部有效
		function _once(...args) {
			fn(...args);
			that.off(type, _once); // 执行一次后注销
		}

		this.tasks[type].push(_once);
	}

	/**
	 * 触发事件(发布)
	 * @param {String} type  事件名称
	 * @param {...any} args  传入的参数,不限个数
	 */
	emit(type, ...args) {
		// 如果该事件没有被注册,则返回
		if (!this.tasks[type]) {
			return;
		}
		// 遍历执行对应的回调数组,并传入参数
		this.tasks[type].forEach((fn) => fn(...args));
	}

	/**
	 * 移除指定回调(取消订阅)
	 * @param {String} type  事件名称
	 * @param {Function} fn  回调函数
	 */
	off(type, fn) {
		const tasks = this.tasks[type];
		// 校验事件队列是否存在
		if (!Array.isArray(tasks)) {
			return;
		}

		// 利用 filter 删除队列中的指定函数
		this.tasks[type] = tasks.filter((cb) => fn !== cb);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值