Online Use | 中文 | Update Log | Feedback bug | Gitee
- Typescript writing
- Multi-terminal support
- Custom event sequence, multiple trigger modes
- Global interception mechanism
- Small size, easy to use
- Support for creating modules to avoid event conflicts
npm i tc-event
import event from 'tc-event';
event.regist('myEvent', (data) => {
console.log('emited!', data);
})
event.emit('myEvent', 'Aha!');
<script src="https://cdn.jsdelivr.net/npm/tc-event/tc-event.min.js"></script>
<script>
TEvent.regist('myEvent', function (data) {
console.log('emited!', data);
})
TEvent.emit('myEvent', 'Aha!');
</script>
For details, please refer to index.d.ts
export interface IEventEmitter {
removed: boolean;
interceptor: IEventInterceptor;
name: string;
getEventNames(): string[]; // 事件枚举
getEvent(): IEventJson<CEvent>;
getEvent(name: TEventName): CEvent;
emit(name: TEventName, data?: any): boolean; // 触发事件
onEmit(fn: IOnInterceptorEmit): void;
regist: IRegistMethod;
registObject(options: IEventRegistOption & {eventName: TEventName}): IListenerItem;
onRegist(fn: IOnInterceptorRegist): void;
checkEvent(name: TEventName): boolean; // 检查是否存在事件
remove: IRemoveMethod;
clear(name?: TEventName | TEventName[]): void;
order(name: TEventName): number;
registNotImmediate(name: TEventName, listener: IEventListener): IListenerItem;
registNotImmediateOnce(name: TEventName, listener: IEventListener): IListenerItem;
registOnce(name: TEventName, listener: IEventListener): IListenerItem;
registSingle(name: TEventName, listener: IEventListener): IListenerItem;
}
export interface IEventStatic extends IEventEmitter {
version: string;
createModule (name: TModuleName): IEventEmitter;
getModule (): IEventJson<IEventEmitter>;
getModule (name: TModuleName): IEventEmitter;
removeModule(name: TModuleName): void;
clearModule(): void;
EventEmitter: typeof EventEmitter;
}
Determine whether the event exists
const eventName = 'test-checkEvent';
const result = [];
result.push(event.checkEvent(eventName));
event.regist(eventName, () => {});
result.push(event.checkEvent(eventName));
event.emit(eventName);
result.push(event.checkEvent(eventName));
event.clear(eventName);
result.push(event.checkEvent(eventName));
event.regist(eventName, () => {});
result.push(event.checkEvent(eventName));
event.clear();
result.push(event.checkEvent(eventName));
console.log(result);
// [false, true, true, false, true, false]
Clear single or all events
const eventName = 'test-clear';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.emit(eventName);
event.clear(eventName);
event.emit(eventName);
event.regist(eventName, {
immediate: false,
listener: () => {
result.push(2);
}
});
event.emit(eventName);
event.clear();
event.emit(eventName);
console.log(result);
// [1, 2]
The immediate parameter indicates whether the current event needs to be triggered immediately if the event has already been triggered when registering an event
const eventName = 'test-immediate';
const result = [];
event.emit(eventName);
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, {
immediate: true,
listener () { result.push(2);}
});
event.regist(eventName, {
immediate: false,
listener () {result.push(3);}
});
console.log(result);
// [1, 2]
The index parameter indicates the position where you want to insert when registering an event
const eventName = 'test-order';
const result = [];
event.regist(eventName, () => {
result.push(1); // 1
});
event.regist(eventName, () => {
result.push(2); // 1 2
});
event.regist(eventName, () => {
result.push(3); // 1 2 3
});
event.regist(eventName, () => {
result.push(4); // 1 2 3 4
});
event.regist(eventName, {
index: 0, // 5 1 2 3 4
listener () {result.push(5);}
});
event.regist(eventName, {
index: 2, // 5 1 6 2 3 4
listener () {result.push(6);}
});
event.regist(eventName, {
index: 1, // 5 7 1 6 2 3 4
listener () {result.push(7);}
});
event.regist(eventName, {
index: 100, // 5 7 1 6 2 3 4 8
listener () {result.push(8);}
});
event.regist(eventName, {
index: -3, // 9 5 7 1 6 2 3 4 8
listener () {result.push(9);}
});
event.emit(eventName);
console.log(result);
// [9, 5, 7, 1, 6, 2, 3, 4, 8]
Global interceptor, support onRegist and onEmit
const eventName1 = 'test-interceptor1';
const eventName2 = 'test-interceptor2';
const result = [];
event.onRegist(({name, item}) => {
result.push(`onRegist: ${name}`);
});
event.onEmit(({name, item, data, firstEmit}) => {
result.push(`onEmit: ${name} ${data} ${firstEmit}`);
});
event.regist(eventName1, () => {});
event.regist(eventName2, () => {});
event.emit(eventName1, `${eventName1} data`);
event.emit(eventName2, `${eventName2} data`);
event.emit(eventName2, `${eventName2} data2`);
console.log(result);
/*
[
'onRegist: test-interceptor1',
'onRegist: test-interceptor2',
'onEmit: test-interceptor1 test-interceptor1 data true',
'onEmit: test-interceptor2 test-interceptor2 data true',
'onEmit: test-interceptor2 test-interceptor2 data2 false'
]
*/
once parameter is only triggered sequentially
const eventName = 'test-once';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, {
once: true,
listener () { result.push(2);}
});
event.regist(eventName, {
once: false,
listener () {result.push(3);}
});
event.emit(eventName);
event.emit(eventName);
console.log(result);
// [1, 2, 3, 1, 3]
The times parameter is the number of times the monitor is triggered
const eventName = 'test-times';
const result = [];
event.regist(eventName, {
times: 1,
listener () { result.push(1);}
});
event.regist(eventName, {
times: 2,
listener () { result.push(2);}
});
event.regist(eventName, {
times: 3,
listener () { result.push(3);}
});
event.emit(eventName);
event.emit(eventName);
event.emit(eventName);
event.emit(eventName);
// [1, 2, 3, 2, 3, 3]
Control the sequence number of the insertion event (different from the index parameter)
const eventName = 'test-order';
const result = [];
event.regist(eventName, () => {
result.push(1); // 1
});
event.regist(eventName, () => {
result.push(2); // 1 2
});
event.regist(eventName, {
order: 0, // 0 1 2
listener () {result.push(3);}
});
event.regist(eventName, {
order: 1, // 0 1 *1 2
listener () {result.push(4);}
});
event.regist(eventName, {
order: 1, // 0 1 *1 **1 2
listener () {result.push(5);}
});
event.regist(eventName, {
order: 1, // 0 ***1 1 *1 **1 2
orderBefore: true,
listener () {result.push(6);}
});
event.regist(eventName, {
order: 10, // 0 ***1 1 *1 **1 2 10
listener () {result.push(7);}
});
event.regist(eventName, () => { // 0 ***1 1 *1 **1 2 3 10
result.push(8);
});
event.emit(eventName);
console.log(result);
Singleton monitoring mode, enabling the single parameter for an event name will overwrite all previous monitoring functions for the event
And after this event, there is no need to carry the single parameter
When the single parameter is enabled, the index order orderBefore parameter is invalid
const eventName = 'test-single';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.emit(eventName);
// Test coverage old method
event.regist(eventName, {
single: true,
immediate: false,
listener: () => {
result.push(2);
}
});
event.emit(eventName);
event.clear(eventName);
event.regist(eventName, {
single: true,
listener () { result.push(3);}
});
event.regist(eventName, {
single: true,
listener () { result.push(4);}
});
event.emit(eventName);
// Test single parameter cache
event.regist(eventName, {
immediate: false,
listener () { result.push(5);}
});
event.emit(eventName);
console.log(result);
// [1, 2, 4, 5]
The name parameter is used to add a parameter to a monitor
The default value is eventName + id
const eventName = 'test-name';
const item1 = event.regist(eventName, () => {
});
const item2 = event.regist(eventName, {
name: 'listener-name',
listener () {}
});
// item1.name === 'test-name-1'
// item2.name === 'listener-name'
The head parameter is used to add the listener to the event head
const eventName = 'test-head';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, {
order: -1,
listener () {result.push(2);}
});
event.regist(eventName, {
index: -1,
listener () {result.push(3);}
});
event.regist(eventName, {
head: true,
listener () {result.push(4);}
});
event.regist(eventName, {
head: true,
listener () {result.push(5);}
});
event.emit(eventName);
// result: [5, 4, 3, 2, 1]
The tail parameter is used to add the listener to the end of the event
const eventName = 'test-tail';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, {
order: 100,
listener () {result.push(2);}
});
event.regist(eventName, {
index: 100,
listener () {result.push(3);}
});
event.regist(eventName, {
listener () {result.push(4);}
});
event.regist(eventName, {
tail: true,
listener () {result.push(5);}
});
event.regist(eventName, {
tail: true,
listener () {result.push(6);}
});
event.emit(eventName);
// result: [1, 4, 2, 3, 5, 6]
Get the serial number of a monitor
const eventName = 'test-order-fn';
const result = [];
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, () => {
result.push(2);
});
const e1 = event.regist(eventName, () => {
result.push(3);
});
const e2 = event.regist(eventName, {
order: 1,
listener () { result.push(4);}
});
event.regist(eventName, () => {
result.push(5);
});
event.emit(eventName);
console.log([result, event.order(eventName), e1.order, e2.order]);
// [[1, 4, 2, 3, 5], 4, 3, 1
Remove event listener
const eventName = 'test-remove';
const result = [];
const l4 = () => { result.push(4); };
const l5 = () => { result.push(5); };
const l6 = () => { result.push(6); };
const l7 = () => { result.push(7); };
event.regist(eventName, () => {
result.push(1);
});
event.regist(eventName, () => {
result.push(2);
});
event.regist(eventName, () => {
result.push(3);
event.remove(eventName, l4, true);
event.remove(eventName, l5);
event.regist(eventName, l7);
});
event.regist(eventName, l4);
event.regist(eventName, l5);
event.regist(eventName, l6);
event.remove(eventName, l6);
event.emit(eventName);
event.emit(eventName);
console.log(result);
// [1, 2, 3, 7, 5, 1, 2, 3, 7, 7]
event.registNotImmediate('xxx', ()=>{})
// equals
event.regist('xxx', {
immediate: false,
listener: ()=>{}
})
event.registOnce('xxx', ()=>{})
// equals
event.regist('xxx', {
once: true,
listener: ()=>{}
})
event.registNotImmediateOnce('xxx', ()=>{})
// equals
event.regist('xxx', {
immediate: false,
once: true,
listener: ()=>{}
})
event.registSingle('xxx', ()=>{})
// equals
event.regist('xxx', {
single: true,
listener: ()=>{}
})
The second parameter of the monitoring function is a json, which contains three attributes
- firstEmit indicates whether the monitor is triggered for the first time
- remove is the method to remove the current monitor
- clear is the method to remove the current event
- item is the current monitoring object
event.regist('xxx', (data, {firstEmit, item, remove, clear})=>{
})
The regist function will enable chained calls when referring to the incoming event name
All parameters can be called by chain, all apis are optional, and finally need to be triggered through the listen method
event.regist('xxx')
.index(1)
.order(1)
.orderBefore()
.notImmediate()
.single()
.once()
.times(1)
.listener()
.name('xxx')
.head()
.tail()
.listen();
The declaration file is as follows
interface IEventLink {
single: (single: boolean) => IEventLink;
notImmediate: (immediate: boolean) => IEventLink;
once: (once: boolean) => IEventLink;
index: (index: number) => IEventLink;
order: (order: number) => IEventLink;
orderBefore: (orderBefore: boolean) => IEventLink;
listener: (listener: IEventListener) => IEventLink;
name: (name: string) => IEventLink;
head: () => IEventLink;
tail: ()=> IEventLink;
times: (times: number)=> IEventLink;
listen: (listener?: IEventListener) => IListenerItem;
}
- createModule
const result = [];
const name = 'module_event';
const moduleA = event.createModule('A');
const moduleB = event.createModule('B');
moduleA.regist(name, data => {result.push('A' + data);});
moduleB.regist(name, data => {result.push('B' + data);});
moduleA.emit(name, 1);
moduleA.emit(name, 2);
console.log(result);
- getModule
event.createModule('A');
event.createModule('B');
console.log([
event.getModule('A').moduleName,
event.getModule('B').moduleName,
]);