我有一个角度应用程序,偶尔需要从服务器同步数据。我想显示上次同步执行的时间。
我已经有一个获取此时间的函数,因为我使用它仅同步上次同步后所做的更改:
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
的值永远不会更新。我错过了什么?
我对可观察量还很陌生,所以我不确定我是否正确理解了订阅的概念。我认为通过订阅返回可观察值的函数,一旦可观察值发生变化,就会触发此订阅。难道不是这样吗
可观察量是随时间变化的数据流。 Oservable 可以做 3 件事:
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
代码中所做的事情。