javascript RXJS观察者会减慢彼此的速度

yjghlzjz  于 10个月前  发布在  Java
关注(0)|答案(1)|浏览(59)

我有一个页面,左边是文档列表(有可点击的项目,每个项目将选择一个文档),右边是所选文档的实际内容,它占据了页面的大部分。问题是,当点击一个大文档时,会导致显示延迟,但更重要的是,所选的菜单项(来自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);
                })
            )
        )
    );

wecizke3

wecizke31#

我的猜测是,您通过python作为(从JavaScript的Angular 来看)同步操作获取信息。
我的第二个猜测是,因为selectedDocument$没有使用share()运算符,each observer正在递增this.switcher,这是(或可能很快)把事情搞砸了。
两者都可以通过改变尝试来解决

selectedDocument$: Observable<EvahubDocument> = this.currentDocumentId$.pipe(
    combineLatestWith(this.currentPageIndex$, this.userLogs$),
    map(([docId, cpi, ls]) => {
        return ls[this.switcher++ % 3];
    }),
    shareReplay(1),
    observeOn(asyncScheduler)
);

字符串
shareReplay确保迟到的观察者从发出的最新值开始。此外,如果没有它,可观察对象和操作符将按每个观察者执行。
observeOn在异步调度器上发出值。

相关问题