管道 shareReplay 与 ReplaySubject.observableOf 的 Observable

Observable of pipe shareReplay vs. ReplaySubject.observableOf

shareReplay 没有像我预期的那样工作。从文档中我希望以下代码是等效的。

@Injectable( {
    providedIn: 'root'
} )
export class CartService {

    private list: InventoryItem[] = [];
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = of( this.list ).pipe(
        shareReplay( 1 )
    );

    constructor() {}

    addItem( item: InventoryItem ) {
        this.list.push( item );
    }
}

@Injectable( {
    providedIn: 'root'
} )
export class CartService {

    private list: InventoryItem[] = [];
    private subject = new ReplaySubject<ReadonlyArray<Readonly<InventoryItem>>>(1);
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = this.subject.asObservable();

    constructor() {}

    addItem( item: InventoryItem ) {
        this.list.push( item );
        this.subject.next(this.list);
    }
}

然而,只有第二个版本在调用 addItem(...) 时所有订阅者都会收到事件。

第一个示例仅适用于我的根组件中的一个实例,但不适用于我使用类似语法的任何其他组件。

[matBadge]="(cartService.cart | async)?.length"

我已经确认只创建了一个服务实例,谁能告诉我第一段代码中发生了什么?

你的例子不一样。

private list: InventoryItem[] = [];
    cart: Observable<ReadonlyArray<Readonly<InventoryItem>>> = of( this.list ).pipe(
        shareReplay( 1 )
    );

of(this.list) 将采用 current this.list 并且当您订阅时您会获得该列表,但如果您订阅 this.list.push(...)。您将不得不重新订阅。

另一方面,当您使用主题在列表中发出更改信号时,您的订阅者将再次收到通知。

所以这很关键:

this.subject.next(this.list);