vtils
Version:
一个面向业务的 JavaScript/TypeScript 实用程序库。
178 lines (172 loc) • 5.53 kB
JavaScript
import _createForOfIteratorHelperLoose from "@babel/runtime/helpers/esm/createForOfIteratorHelperLoose";
import { castArray } from 'lodash-uni';
/**
* 事件巴士,管理事件的发布与订阅。
*
* @template TListeners 事件名称及其对应的回调描述
* @example
* ```typescript
* const bus = new EventBus<{
* success: (payload: { message: string }) => any
* }>()
* bus.on('success', ({ message }) => console.log(message))
* bus.emit('success', { message: '提交成功' })
* // => 控制台输出: 提交成功
* ```
*/
export var EventBus = /*#__PURE__*/function () {
/**
* 构造函数。
*/
function EventBus(options) {
this.options = options;
/**
* 回调列表。
*/
this.callbacks = Object.create(null);
}
var _proto = EventBus.prototype;
_proto.on = function on(eventNames, callback) {
var _this = this,
_this$options$beforeO,
_this$options;
if (Array.isArray(eventNames)) {
var offs = [];
var _loop = function _loop() {
var eventName = _step.value;
offs.push(
// @ts-ignore
_this.on(eventName, function () {
var _callback, _callback2;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return callback((_callback = {}, _callback[eventName] = args[0], _callback), (_callback2 = {}, _callback2[eventName] = args, _callback2));
}));
};
for (var _iterator = _createForOfIteratorHelperLoose(eventNames), _step; !(_step = _iterator()).done;) {
_loop();
}
return function () {
return offs.forEach(function (off) {
return off();
});
};
}
if (!this.callbacks[eventNames]) {
this.callbacks[eventNames] = [];
}
callback = (_this$options$beforeO = (_this$options = this.options) == null || (_this$options = _this$options.beforeOn) == null || (_this$options = _this$options[eventNames]) == null ? void 0 : _this$options.call(this, callback)) != null ? _this$options$beforeO : callback;
var index = this.callbacks[eventNames].indexOf(callback);
if (index === -1) {
this.callbacks[eventNames].push(callback);
}
return function () {
return _this.off(eventNames, callback);
};
}
/**
* 订阅事件,但只订阅一次即取消订阅。
*
* @param eventName 事件名称
* @param callback 事件触发回调
* @returns 返回取消订阅的函数
*/;
_proto.once = function once(eventName, callback) {
var off = this.on(eventName, function () {
off();
callback.apply(void 0, arguments);
});
return off;
}
/**
* 取消订阅事件,若没有指定回调,则取消所有回调。
*
* @param eventName 事件名称
* @param callback 事件触发回调
*/;
_proto.off = function off(eventName, callbackOrTag) {
if (this.callbacks[eventName] && callbackOrTag) {
if (typeof callbackOrTag === 'function') {
var _index = this.callbacks[eventName].indexOf(callbackOrTag);
if (_index > -1) {
this.callbacks[eventName].splice(_index, 1);
}
} else {
var _index2 = this.callbacks[eventName].length;
while (_index2--) {
if (this.callbacks[eventName][_index2].__EVENT_BUS_TAG__ != null && this.callbacks[eventName][_index2].__EVENT_BUS_TAG__ === callbackOrTag) {
this.callbacks[eventName].splice(_index2, 1);
}
}
}
} else {
delete this.callbacks[eventName];
}
}
/**
* 发布事件。
*
* @param eventNameAndContext 事件名称和上下文
* @param args 传给事件回调的参数
* @returns 返回各事件回调的返回结果组成的数组
*/;
_proto.emit = function emit(
// @ts-ignore
eventName) {
var _this$options2;
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
var _ref = typeof eventName === 'object' ? eventName : {
name: eventName
},
name = _ref.name,
context = _ref.context,
tag = _ref.tag,
filter = _ref.filter;
var callbacks = (this.callbacks[name] || []).slice();
if (tag != null) {
callbacks = callbacks.filter(function (callback) {
return callback.__EVENT_BUS_TAG__ != null && tag === callback.__EVENT_BUS_TAG__;
});
}
if (typeof filter === 'function') {
callbacks = callbacks.filter(filter);
}
(_this$options2 = this.options) == null || (_this$options2 = _this$options2.beforeEmit) == null || (_this$options2 = _this$options2[name]) == null || _this$options2.call(this, context);
return callbacks.map(function (callback) {
return callback.call.apply(callback, [context].concat(args));
});
}
/**
* 局部执行。
*
* @param fn 执行函数
* @returns 可以返回一个或多个取消订阅的函数
*/;
_proto.run = function run(fn) {
var res = fn(this);
return function () {
if (res) {
castArray(res).forEach(function (off) {
return off();
});
}
};
}
/**
* 清空事件订阅。
*/;
_proto.clear = function clear() {
this.callbacks = Object.create(null);
}
/**
* 销毁。
*/;
_proto.destroy = function destroy() {
// @ts-ignore
this.callbacks = null;
};
return EventBus;
}();