通過Rxjs五行程式碼實現EventBus

肥飝貓發表於2018-07-28

背景

訊息傳遞是目前開發之中最常用的一個元件。沒有之一。不同的訊息傳遞方式各有千秋,但是不論如何。合適的 才是最好的。

在很大一部分系統中。訊息的傳遞還沒有複雜到需要各種類庫去搞定。徒增新同學的上手成本。 可能需要監聽和傳遞的資料只有幾種,所以ngrx、ngxs、redux、mobx、vuex等庫的引入只會帶來額外的複雜度。所以用RXJS直接做一個BUS吧。

EventBus

EventBus是一個事件釋出/訂閱框架,通過解耦釋出者和訂閱者簡化事件傳遞。特別是在多層控制器巢狀的情況下。

EventBus最大的特點就是:簡潔、解耦。在沒有EventBus之前我們通常用廣播來實現監聽,或者自定義介面函式回撥,比如ng1的$broadcast$emit、VUE的$emit$on等。

圖片摘自EventBus GitHub主頁

廢話少說 直接上程式碼

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable()
export class PubSubService {
pub = new Subject<Event>();
pub$ = this.pub.asObservable();
publish(event: Event) {
this.pub.next(event);
}
}
export class Event {
type: EventType;
data: any;
}
export enum EventType {
type1,
type2
}
複製程式碼

完成。。如果不算上定義類和列舉。一共五行程式碼。老鐵沒毛病吧。

使用方法


// 元件初始化的時候訂閱
initOnCompanyChange() {
if (this.pubSubService.pub$.subscribe) {
this.subscription = this.pubSubService.pub$.pipe(
// 可以看到經過這個主題的所有資料
tap(event => {
console.log(`接收到資料`);
console.log(event.data);
}),
// 我們只需要關心自己需要的型別的事件和資料
filter(event => event.type === EventType.type1)
).subscribe(event => {
// 拿到之後,就可以為所欲為了
console.log(`接受到TYPE1資料:`);
console.log(event.data);
});
}
}

// 傳送型別為type1的事件和資料
testChangeType1() {
this.pubSubService.publish({
type: EventType.type1,
data: {
key: '來了來了',
value: 'ooooooo'
}
});
}

// 傳送型別為type2的事件和資料
testChangeType2() {
this.pubSubService.publish({
type: EventType.type2,
data: {
key: '又來了又來了',
value: 'NNNNNN'
}
});
}

// 元件銷燬的時候取消訂閱,避免記憶體洩露
ngOnDestroy(): void {
this.subscription.unsubscribe();
}

複製程式碼

文中的主題沒有快取的功能 如果需要 可以吧Subject 換成BehaviorSubject 具體可以看Subject, BehaviorSubject, ReplaySubject, AsyncSubject 示例程式碼github

相關文章