订阅 observable 不会触发值更新

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

我有一个角度应用程序,偶尔需要从服务器同步数据。我想显示上次同步执行的时间。

我已经有一个获取此时间的函数,因为我使用它仅同步上次同步后所做的更改:

fetchLastSyncDate(): Observable<Date> {
    return this.ormService.manager$.pipe(
      switchMap(manager => manager.find(OfflineStatusEntity)),
      map(statusArr => statusArr[0]!.lastSync || new Date(0))
    );
  }

我在这个函数中开始同步:

synchronizeData(): Observable<void> {
    const syncDate = new Date();
    return this.fetchLastSyncDate().pipe(
      switchMap(modifiedAfter =>
        this.httpClient.get<SynchronizationDto>(
          `${this.baseUrl}/${DateTime.fromJSDate(modifiedAfter).toISO()}`
        )
      ),
      switchMap(data => from(this.updateDataFromServer(data, syncDate)))
    );
  }

我在这里更新同步日期:

private async updateDataFromServer(
    data: SynchronizationDto,
    syncStart: Date
  ): Promise<void> {
    ...
     // save sync date
    const manager = (await firstValueFrom(this.ormService.dataSource$)).manager;
    const status = (await manager.find(OfflineStatusEntity))[0]!;
    status.lastSync = syncStart;
    await manager.save(status);
}

最后我尝试像这样订阅

fetchLastSyncDate()

export class MyComponent implements OnInit {
    subscription = new Subscription();
    lastSyncTime: string | null = null;

    ngOnInit(): void {
      this.subscription.add(
        this.synchronzationDataService.fetchLastSyncDate().subscribe(newSyncDate => {
          this.lastSyncTime = newSyncDate.toLocaleString('de-CH');
          this.changeDetectorRef.markForCheck();
        })
      );
    }
}

当我第一次打开应用程序时,我会得到最新同步的正确时间。但是,当我运行同步时,

lastSyncTime
的值永远不会更新。我错过了什么?

我对可观察量还很陌生,所以我不确定我是否正确理解了订阅的概念。我认为通过订阅返回可观察值的函数,一旦可观察值发生变化,就会触发此订阅。难道不是这样吗

angular typescript rxjs observable
1个回答
0
投票

可观察量是随时间变化的数据流。 Oservable 可以做 3 件事:

  • 通知数据
  • 错误
  • 完成 一旦完成,Observable 就无法再通知。

http 调用是 Observables 的一个特例。它们是仅在数据返回后发出通知然后完成的流(如果发生不良情况则发出错误)。将 http 调用映射为 Observable 有意义的原因是,一旦触发,它们就会异步通知结果,因此它们代表“一段时间内的数据流”。

如果映射为 Observable,则订阅 Observable 时会触发 http 调用。由于在您的情况下,订阅发生在

ngOnInit
方法中,因此 “您将获得首次打开应用程序时的时间”

如果你想再次“获得正确的时间”,那么你必须以某种方式再次运行以下代码

    this.synchronzationDataService.fetchLastSyncDate().subscribe(newSyncDate => {
        this.lastSyncTime = newSyncDate.toLocaleString('de-CH');
        this.changeDetectorRef.markForCheck();
}

我怀疑当你再次说“你运行同步”时,你的意思是你订阅了

synchronizeData()
返回的Observable,但这不足以完成你在
ngOnInit
代码中所做的事情。

© www.soinside.com 2019 - 2024. All rights reserved.