我需要一个返回单个值但没有初始值的 Angular Observable

问题描述 投票:0回答:1

我需要像 Observable 这样的东西,它只调用一次 Web 服务,并将其结果返回给所有订阅者。订阅可能发生在通话之前或之后。我怎样才能做到这一点?

A

Subject
将为所有在之前而非之后订阅的客户提供答案。

const s: Subject<number> = new Subject(); s.next(1); s.subscribe(x => {console.log(x)}); // will not print anything
A 

BehaviourSubject

 需要一个虚拟初始值,在调用之前订阅的客户端将获得虚拟值而不是正确的值。

const s: BehaviorSubject<number> = new BehaviorSubject(123); s.subscribe(x => {console.log(x)}); // will print dummy value 123, then 1 s.next(1);
我尝试创建自己的

Observable

,但是在这种情况下,网络服务可能会被多次调用

let val: number|undefined = undefined; const s = new Observable((observer) => { if (val !== undefined) { observer.next(val); } else { doMyHttpCall().subscribe({ response => { this.val = 1; observer.next(val); }); } }); s.subscribe(x => {console.log(x)}); s.subscribe(x => {console.log(x)}); // two clients may give two calls
正确的做法是什么?

angular typescript rxjs angular-http
1个回答
0
投票
使用回复主题

import { ReplaySubject } from 'rxjs'; function createBehaviorSubjectWithoutInitialValue<T>(): ReplaySubject<T> { return new ReplaySubject<T>(1); } // Usage const behaviorSubjectWithoutInitialValue = createBehaviorSubjectWithoutInitialValue<string>(); // Subscribe to the subject behaviorSubjectWithoutInitialValue.subscribe(value => { console.log(value); // Output: YourValue }); // Emit a value behaviorSubjectWithoutInitialValue.next('YourValue');
使用共享重放

import { Observable } from 'rxjs'; import { shareReplay } from 'rxjs/operators'; function createBehaviorSubjectWithoutInitialValue<T>(source: Observable<T>): Observable<T> { return source.pipe(shareReplay(1)); } // Usage const source = new Observable<string>(subscriber => { // Emit a value subscriber.next('YourValue'); subscriber.complete(); }); const behaviorSubjectWithoutInitialValue = createBehaviorSubjectWithoutInitialValue(source); // Subscribe to the subject behaviorSubjectWithoutInitialValue.subscribe(value => { console.log(value); // Output: YourValue }); // Later subscriptions will also get the most recent value behaviorSubjectWithoutInitialValue.subscribe(value => { console.log(value); // Output: YourValue });
    
© www.soinside.com 2019 - 2024. All rights reserved.