我有一个页面,左边是文档列表(有可点击的项目,每个项目将选择一个文档),右边是所选文档的实际内容,它占据了页面的大部分。问题是,当点击一个大文档时,会导致显示延迟,但更重要的是,所选的菜单项(来自EvahubSidenavComponent
)不会立即显示,而是似乎在等待文档内容(在EvahubDocumentsComponent
中)先显示。为什么呢?文档本身可以有10 MB的文本,所以如果需要在一两秒内读取它是可以的,但是左边的菜单项(在evahub-sidenav中)应该立即着色。我在状态存储中有两个关键的观察结果:
currentDocumentId$: Observable<number> = this.select(
state => state.currentUser.currentDocumentId
);
// for simplification, I set so the clicked document is always going from 0 to 3, so switcher is serving that purpose as index
switcher = 0;
selectedDocument$: Observable<EvahubDocument> = this.currentDocumentId$.pipe(
combineLatestWith(this.currentPageIndex$, this.userLogs$),
map(([docId, cpi, ls]) => {
return ls[this.switcher++ % 3];
})
);
字符串
应用组件观察当前选定文档的id,因此在app.component.ts中我有:
currentDocumentId$ = this.store.currentDocumentId$;
型
在模板(app.component.html
)中,我有一个子组件(EvahubSidenavComponent
),currentDocumentId$
只是作为输入传播到它,所以像这样:
<div *ngIf="{
currentDocumentId: currentDocumentId$ | async,
...
} as asyncData"
>
<evahub-sidenav
...
[selectedDocumentId]="asyncData.currentDocumentId"
...
></evahub-sidenav>
</div>
<router-outlet></router-outlet>
型
Router将依次包含第二个组件(EvahubDocumentsComponent
),它使用存储中的selectedDocument$
,在其模板EvahubDocumentsComponent.html
中如下所示
<div
*ngIf="{
selectedDocument: selectedDocument$ | async,
currentPageIndex: currentPageIndex$ | async
} as asyncData"
>
{{ asyncData.selectedDocument.getDocumentContent() }}
型
并在组件本身中这样处理:
selectedDocument$ = this.store.selectedDocument$;
型
概括一下,导出的可观察量selectedDocument$
以某种方式停止了它的因子可观察量currentDocumentId$
,直到导出的可观察量完成并返回。这不好,我希望他们分开独立处理。我尝试了这个衍生的可观察,结果相同,即。currentDocumentId$被延迟:
selectedDocument$: Observable<any> = this.currentDocumentId$.pipe(
mergeMap(cdi =>
this.currentPageIndex$.pipe(
combineLatestWith(this.userLogs$),
map(uls => {
return uls[1].find(l => l.logId == cdi);
})
)
)
);
型
1条答案
按热度按时间wecizke31#
我的猜测是,您通过python作为(从JavaScript的Angular 来看)同步操作获取信息。
我的第二个猜测是,因为
selectedDocument$
没有使用share()
运算符,each observer正在递增this.switcher
,这是(或可能很快)把事情搞砸了。两者都可以通过改变尝试来解决
字符串
shareReplay
确保迟到的观察者从发出的最新值开始。此外,如果没有它,可观察对象和操作符将按每个观察者执行。observeOn
在异步调度器上发出值。