subscribe.js
(function () {// 全局只有一个事件池let pond = {};// 向事件池中订阅方法const on = function on(type, func) {if (!pond.hasOwnProperty(type)) pond[type] = [];let arr = pond[type];if (arr.includes(func)) return; //去重arr.push(func);};// 从事件池中移除订阅const off = function off(type, func) {let arr = pond[type] || [];if (arr.length === 0) return;let i = 0,item;for (; i < arr.length; i++) {item = arr[i];if (item === func) {// arr.splice(i, 1); //引发数组塌陷arr[i] = null;return;}}};// 通知事件池中,指定类型的方法去执行const fire = function fire(type, ...params) {let arr = pond[type] || [],i = 0,item;for (; i < arr.length; i++) {item = arr[i];if (typeof item === 'function') {item(...params);continue;}// 当期这一项不是函数,则我们把其移除掉arr.splice(i, 1);i--;}};/* 暴露API */let sub = {on,off,fire};if (typeof window !== 'undefined') window.sub = sub;//node环境if (typeof module === 'object' && typeof module.exports === 'object') module.exports = sub;})();
使用方案如下:
setTimeout(() => {
sub.fire('@A', 100, 200);
}, 1000);
const fn1 = (a, b) => console.log(1, a, b);
const fn2 = () => console.log(2);
sub.on('@A', fn1);
sub.on('@A', fn1);
sub.on('@A', fn2);
submit.onclick = function () {
sub.fire('@A');
};
const fn1 = () => console.log(1);
const fn2 = () => {
console.log(2);
// 第一次执行fn2的同时,从事件池中移除fn1/fn2
sub.off('@A', fn1);
sub.off('@A', fn2);
};
const fn3 = () => console.log(3);
const fn4 = () => console.log(4);
const fn5 = () => console.log(5);
sub.on('@A', fn1);
sub.on('@A', fn2);
sub.on('@A', fn3);
sub.on('@A', fn4);
sub.on('@A', fn5);
