mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-13 19:21:56 +01:00
Improve event service (#15353)
Signed-off-by: AllForNothing <sshijun@vmware.com>
This commit is contained in:
parent
5984175a1f
commit
f6801cea57
@ -1,5 +1,6 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { EventService } from "./event.service";
|
||||
import { Subscription } from "rxjs";
|
||||
|
||||
|
||||
describe('EventServiceService', () => {
|
||||
@ -13,4 +14,18 @@ describe('EventServiceService', () => {
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('able to subscribe', () => {
|
||||
let result: string;
|
||||
const sub1 = service.subscribe('testEvent', data => {
|
||||
result = data;
|
||||
});
|
||||
expect(sub1 ).toBeTruthy();
|
||||
expect((sub1 instanceof Subscription)).toEqual(true);
|
||||
service.publish('testEvent', 'resultString');
|
||||
sub1.unsubscribe();
|
||||
expect(result).toEqual('resultString');
|
||||
|
||||
});
|
||||
});
|
||||
|
@ -1,54 +1,73 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Subject } from "rxjs";
|
||||
import { Subscription } from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: "root"
|
||||
})
|
||||
export class EventService {
|
||||
|
||||
private listeners = {};
|
||||
private eventsSubject = new Subject();
|
||||
private events = from(this.eventsSubject);
|
||||
|
||||
constructor() {
|
||||
this.events.subscribe(
|
||||
({name, args}) => {
|
||||
if (this.listeners[name]) {
|
||||
for (let listener of this.listeners[name]) {
|
||||
listener(...args);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
subscribe(name: string, listener): any {
|
||||
if (!this.listeners[name]) {
|
||||
this.listeners[name] = [];
|
||||
private _channels: any = [];
|
||||
/**
|
||||
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
||||
*
|
||||
* @param {string} topic the topic to subscribe to
|
||||
* @param {function} handler the event handler
|
||||
* @return A Subscription to unsubscribe
|
||||
*/
|
||||
subscribe(topic: string, handler: Function): Subscription {
|
||||
if (!this._channels[topic]) {
|
||||
this._channels[topic] = [];
|
||||
}
|
||||
this.listeners[name].push(listener);
|
||||
return {
|
||||
unsubscribe: () => {
|
||||
this.doUnsubscribe(name, listener);
|
||||
}
|
||||
};
|
||||
}
|
||||
doUnsubscribe(name, listener) {
|
||||
this.listeners[name] = this.listeners[name].filter((v) => {
|
||||
return v !== listener;
|
||||
this._channels[topic].push(handler);
|
||||
return new Subscription(() => {
|
||||
this.unsubscribe(topic, handler);
|
||||
});
|
||||
}
|
||||
unsubscribe(name, listener?) {
|
||||
if (this.listeners[name]) {
|
||||
if (!listener) {
|
||||
this.listeners[name] = [];
|
||||
} else {
|
||||
this.doUnsubscribe(name, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
|
||||
*
|
||||
* @param {string} topic the topic to unsubscribe from
|
||||
* @param {function} handler the event handler
|
||||
*
|
||||
*/
|
||||
private unsubscribe(topic: string, handler: Function = null) {
|
||||
let t = this._channels[topic];
|
||||
if (!t) {
|
||||
// Wasn't found, wasn't removed
|
||||
return;
|
||||
}
|
||||
if (!handler) {
|
||||
// Remove all handlers for this topic
|
||||
delete this._channels[topic];
|
||||
return;
|
||||
}
|
||||
// We need to find and remove a specific handler
|
||||
let i = t.indexOf(handler);
|
||||
if (i < 0) {
|
||||
// Wasn't found, wasn't removed
|
||||
return;
|
||||
}
|
||||
t.splice(i, 1);
|
||||
// If the channel is empty now, remove it from the channel map
|
||||
if (!t.length) {
|
||||
delete this._channels[topic];
|
||||
}
|
||||
return;
|
||||
}
|
||||
publish(name, ...args) {
|
||||
this.eventsSubject.next({
|
||||
name,
|
||||
args
|
||||
|
||||
/**
|
||||
* Publish an event to the given topic.
|
||||
* @param topic
|
||||
* @param data
|
||||
*/
|
||||
publish(topic: string, data?: any) {
|
||||
const t = this._channels[topic];
|
||||
if (!t) {
|
||||
return;
|
||||
}
|
||||
t.forEach((handler: any) => {
|
||||
handler(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user