mirror of
https://github.com/goharbor/harbor
synced 2025-04-22 19:10:40 +00: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 { TestBed } from '@angular/core/testing';
|
||||||
import { EventService } from "./event.service";
|
import { EventService } from "./event.service";
|
||||||
|
import { Subscription } from "rxjs";
|
||||||
|
|
||||||
|
|
||||||
describe('EventServiceService', () => {
|
describe('EventServiceService', () => {
|
||||||
@ -13,4 +14,18 @@ describe('EventServiceService', () => {
|
|||||||
it('should be created', () => {
|
it('should be created', () => {
|
||||||
expect(service).toBeTruthy();
|
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 { Injectable } from '@angular/core';
|
||||||
import { from, Subject } from "rxjs";
|
import { Subscription } from "rxjs";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: "root"
|
providedIn: "root"
|
||||||
})
|
})
|
||||||
export class EventService {
|
export class EventService {
|
||||||
|
|
||||||
private listeners = {};
|
private _channels: any = [];
|
||||||
private eventsSubject = new Subject();
|
/**
|
||||||
private events = from(this.eventsSubject);
|
* 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._channels[topic].push(handler);
|
||||||
|
return new Subscription(() => {
|
||||||
|
this.unsubscribe(topic, handler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
/**
|
||||||
this.events.subscribe(
|
* Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
|
||||||
({name, args}) => {
|
*
|
||||||
if (this.listeners[name]) {
|
* @param {string} topic the topic to unsubscribe from
|
||||||
for (let listener of this.listeners[name]) {
|
* @param {function} handler the event handler
|
||||||
listener(...args);
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
subscribe(name: string, listener): any {
|
t.splice(i, 1);
|
||||||
if (!this.listeners[name]) {
|
// If the channel is empty now, remove it from the channel map
|
||||||
this.listeners[name] = [];
|
if (!t.length) {
|
||||||
|
delete this._channels[topic];
|
||||||
}
|
}
|
||||||
this.listeners[name].push(listener);
|
return;
|
||||||
return {
|
|
||||||
unsubscribe: () => {
|
|
||||||
this.doUnsubscribe(name, listener);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Publish an event to the given topic.
|
||||||
|
* @param topic
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
publish(topic: string, data?: any) {
|
||||||
|
const t = this._channels[topic];
|
||||||
|
if (!t) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
doUnsubscribe(name, listener) {
|
t.forEach((handler: any) => {
|
||||||
this.listeners[name] = this.listeners[name].filter((v) => {
|
handler(data);
|
||||||
return v !== listener;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
unsubscribe(name, listener?) {
|
|
||||||
if (this.listeners[name]) {
|
|
||||||
if (!listener) {
|
|
||||||
this.listeners[name] = [];
|
|
||||||
} else {
|
|
||||||
this.doUnsubscribe(name, listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
publish(name, ...args) {
|
|
||||||
this.eventsSubject.next({
|
|
||||||
name,
|
|
||||||
args
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user