UNPKG

observer-ax

Version:
107 lines (95 loc) 3.65 kB
import { SubjectObserver } from './Subject'; import { Observer } from './Observer'; import { ItemBus } from '../models/Item.model'; import { NotifyObject } from '../models/NotifyObject.model'; /** * The Subject owns some important state and notifies observers when the state * changes. */ export class ConcreteSubjectObserver implements SubjectObserver { /** * @type {ItemBus[]} Data to notify */ private _items: ItemBus[] = []; private _receivers: { [key: string]: Observer[] } = {}; constructor(private defaultTriesCount: number = 3) { } protected getTopicReceivers(topic: string = 'ALL'): Observer[] { if (!this.receivers[topic]) { return []; } return this.receivers[topic]; } protected retryPublish(topic: string, item: NotifyObject, receiver: Observer, tries: number = 1) { for (var i = 0; i < tries; i++) { try { receiver.update(item, { topic: topic, pendingItems: this._items.length }); break; } catch (error) { console.error(error); } } } public async notifyNow(item: ItemBus): Promise<void> { if (item.tries === 0) { item.tries = this.defaultTriesCount; } const receivers = this.getTopicReceivers(item.topic); receivers.map((receiver: Observer) => new Promise(resolve => resolve(this.retryPublish(item.topic, item.data, receiver, item.tries)))); } public async notify(): Promise<void> { while (this._items.length > 0) { const item = this._items.shift() as ItemBus; const receivers = this.getTopicReceivers(item.topic); console.log(receivers); receivers.map((receiver: Observer) => new Promise(resolve => resolve(this.retryPublish(item.topic, item.data, receiver, item.tries)))); } } public attach(receiver: Observer, topic: string = 'ALL') { if (!this.receivers[topic]) { this.receivers[topic] = []; } const isExist = this.receivers[topic].includes(receiver); if (isExist) { return console.log('Subject: Observer has been attached already.'); } this.receivers[topic].push(receiver); } public detach(receiver: Observer, topic: string = 'ALL') { if (!this.receivers[topic]) { return; } const observerIndex = this.receivers[topic].indexOf(receiver); if (observerIndex === -1) { return console.log('Subject: Nonexistent observer.'); } this.receivers[topic] = this.receivers[topic].filter(item => item !== receiver); } asObserver(): Observer { const clazz = new class Concrete implements Observer { data: NotifyObject; options?: any; callback: any; update(data: NotifyObject, options?: any) { this.data = data; this.options = options; if (this.callback) this.callback(this.data.data, this.options); } subscribe(callback: (data: any, options?: any) => any) { this.callback = callback; } }(); this.attach(clazz); return clazz; } get receivers(): any { return this._receivers; } set items(values: ItemBus[]) { this._items.push(...values); } set item(value: ItemBus) { this._items.push(value); } }