如果 rxjs 仍在加载数据,如何返回数据或等待

2024-01-04

我有一个服务,它使用 Observable 在其构造函数中加载一些数据。然后在稍后的某个时间可以使用 getter 检索数据。如果数据存在,它应该立即返回数据。或者等待加载完成(如果仍在进行中)。我想出了以下示例(代码在 Typescript 中):

class MyService {
    private loadedEvent = new Subject<any>();
    private loaded = false;
    private data: any;

    constructor(
        private dataService: DataService
    ) {
        this.dataService.loadData().subscribe(data => {
            this.data = data;
            this.loaded = true;
            this.loadedEvent.next(null);
        });
    }

    public getDataOrWait(): Observable<any> {
        if (this.loaded) { // A
            return of(this.data);
        }
        return new Observable((observer: Observer<any>) => {
            const subscription = this.loadedEvent.subscribe(() => { // B
                observer.next(this.data);
                observer.complete();
                subscription.unsubscribe();
            });
        });
    }
}

有没有更简单的方法来做到这一点?这一定是一个常见的模式。

另外,我认为如果在执行位于标记 A 和 B 的行之间时加载完成,则存在竞争条件(我不确定这里是否涉及线程 - 然而数据是异步加载的)。


您所要做的就是使用分享重播() https://www.learnrxjs.io/operators/multicasting/sharereplay.html操作员:

class MyService {
    public data$: Observable<any>;
    public loaded$: Observable<boolean>;

    constructor(private dataService: DataService) {
        this.data$ = this.dataService.loadData().pipe(
            shareReplay(1);
        );
        this.loaded$ = this.data$.pipe(
           mapTo(true),
           startWith(false)
        );
    }
}

The shareReplay运算符是一个多播运算符,它将向所有订阅者发出相同的先前值。订阅者将等待,直到第一个值可用。

然后你可以使用它data$创建一个loaded$可观察到的会发射false until data$最后发出一个值,然后它会一直发出true当值准备好时。

或者,您可以有data$ emit a null在数据准备好之前,然后是数据。下游有一些逻辑上的好处,允许您在数据准备好或未准备好时创建新的可观察量。

        this.data$ = this.dataService.loadData().pipe(
            startWith(null),
            shareReplay(1);
        );

你必须打电话myService.data$.subscribe()触发流的第一次读取以使数据准备好。您可以在构造函数中执行此操作,但请记住,Angular 在首次使用之前不会创建服务。如果您希望立即加载数据,请在路由中使用解析器或将服务注入到NgModule构造函数并在那里订阅。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果 rxjs 仍在加载数据,如何返回数据或等待 的相关文章

随机推荐