UNPKG

mini-program-event-store

Version:

A small responsive system suitable for handling data responsive issues in mini program development

253 lines (222 loc) 7.3 kB
class EventBus { constructor() { this.eventBus = {}; } /** * * @param {事件名} eventName * @param {事件回调函数} eventCallback * @param {绑定this} thisArg * @returns this */ on(eventName, eventCallback, thisArg) { if (typeof eventName !== "string") { throw new TypeError("the event name must be string type"); } if (typeof eventCallback !== "function") { throw new TypeError("the event callback must be function type"); } /** * 将事件命收集起来,比如: * eventBus= { why: [{eventCallback, thisArg}] } */ let handlers = this.eventBus[eventName]; if (!handlers) { handlers = []; this.eventBus[eventName] = handlers; } handlers.push({ eventCallback, thisArg, }); /** * 返回 this 是为了支持链式调用 * eventBus.on('event1', callback1) * .on('event2', callback2) * .once('event3', callback3); * */ return this; } once(eventName, eventCallback, thisArg) { if (typeof eventName !== "string") { throw new TypeError("the event name must be string type"); } if (typeof eventCallback !== "function") { throw new TypeError("the event callback must be function type"); } // 创建一个新的回调函数 tempCallback,当接收到emit时,传给 原始的 eventCallback const tempCallback = (...payload) => { // 先把自己 的回调函数 移除 this.off(eventName, tempCallback); // 然后执行原始的 eventCallback,将数据传回去 eventCallback.apply(thisArg, payload); }; return this.on(eventName, tempCallback, thisArg); } /** * * @param {事件名} eventName * @param {参数载荷} payload * @returns this * * 在eventBus中查找对应的事件名,如果存在,则执行对应的回调函数 */ emit(eventName, ...payload) { if (typeof eventName !== "string") { throw new TypeError("the event name must be string type"); } const handlers = this.eventBus[eventName] || []; handlers.forEach((handler) => { handler.eventCallback.apply(handler.thisArg, payload); }); return this; } /** * * @param {要取消监听的事件名} eventName * @param {回调函数} eventCallback */ off(eventName, eventCallback) { if (typeof eventName !== "string") { throw new TypeError("the event name must be string type"); } if (typeof eventCallback !== "function") { throw new TypeError("the event callback must be function type"); } // eventBus= { why: [ {callback1, thisArg}, {callback2, thisArg}], {callback3, thisArg}] } // 找到对应的 回调函数数组 const handlers = this.eventBus[eventName]; if (handlers && eventCallback) { const newHandlers = [...handlers]; for (let i = 0; i < newHandlers.length; i++) { const handler = newHandlers[i]; if (handler.eventCallback === eventCallback) { // 将取消监听的回调函数 删除 const index = handlers.indexOf(handler); handlers.splice(index, 1); } } } if (handlers.length === 0) { delete this.eventBus[eventName]; } } clear() { this.emitBus = {}; } // 检查是否存在指定名称的事件 hasEvent(eventName) { return Object.keys(this.emitBus).includes(eventName); } } function isObject(obj) { var type = typeof obj; return type === "object" && !!obj; } class EventStore { constructor(options) { if (!isObject(options.state)) { throw new TypeError("the state must be object type"); } if (options.actions && isObject(options.actions)) { const values = Object.values(options.actions); for (const value of values) { if (typeof value !== "function") { throw new TypeError("the value of actions must be a function"); } } this.actions = options.actions; } this.state = options.state; this._observe(options.state); this.event = new EventBus(); this.eventV2 = new EventBus(); } _observe(state) { const _this = this; Object.keys(state).forEach((key) => { let _value = state[key]; Object.defineProperty(state, key, { get: function () { return _value; }, set: function (newValue) { if (_value === newValue) return; /** * 这里没有赋值(state[key] = "newValue"),为什么对应的value值是最新的? * get 返回的是_value */ _value = newValue; // 用于 onState _this.event.emit(key, _value); // 用于 onStates _this.eventV2.emit(key, { [key]: _value }); }, }); }); } // 监听 stateKey 的变化 onState(stateKey, stateCallback) { const keys = Object.keys(this.state); if (keys.indexOf(stateKey) === -1) { throw new Error("the state does not contain your key"); } // 收集依赖 this.event.on(stateKey, stateCallback); // callback if (typeof stateCallback !== "function") { throw new TypeError("the event callback must be function type"); } // 立即执行回调函数,返回stateKey的值。后面stateKey变化了,执行bus里面的回调就行了 const value = this.state[stateKey]; stateCallback.apply(this.state, [value]); } // ["name", "age"] callback1 // ["name", "height"] callback2 // 监听 多个stateKey 的变化 onStates(statekeys, stateCallback) { const keys = Object.keys(this.state); const value = {}; for (const theKey of statekeys) { if (keys.indexOf(theKey) === -1) { throw new Error("the state does not contain your key"); } this.eventV2.on(theKey, stateCallback); value[theKey] = this.state[theKey]; } stateCallback.apply(this.state, [value]); } offStates(stateKeys, stateCallback) { const keys = Object.keys(this.state); stateKeys.forEach((theKey) => { if (keys.indexOf(theKey) === -1) { throw new Error("the state does not contain your key"); } this.eventV2.off(theKey, stateCallback); }); } offState(stateKey, stateCallback) { const keys = Object.keys(this.state); if (keys.indexOf(stateKey) === -1) { throw new Error("the state does not contain your key"); } this.event.off(stateKey, stateCallback); } // 更改 stateKey 的值 setState(stateKey, stateValue) { // 触发set -> emit this.state[stateKey] = stateValue; } dispatch(actionName, ...args) { if (typeof actionName !== "string") { throw new TypeError("the action name must be string type"); } if (Object.keys(this.actions).indexOf(actionName) === -1) { throw new Error("this action name does not exist, please check it"); } const actionFn = this.actions[actionName]; actionFn.apply(this, [this.state, ...args]); } } export { EventBus, EventStore };