RXJS/Angular 在多个订阅者上防止多个 HTTP [英] RXJS/Angular Prevent multiple HTTP on multiple subscribers

查看:46
本文介绍了RXJS/Angular 在多个订阅者上防止多个 HTTP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有mainData"服务,它由三部分组成:

I have "mainData" service, it consists of 3 parts:

  • currentPage 被分页器组件用来切换页面.可以随时更新.
  • folders 包含当前文件夹中的所有文件夹.有 2 个组件使用了这个 observable(文件夹内容列表的类型)
  • files 包含当前文件夹中的所有文件.有 3 个组件使用这个 observable(文件夹内容列表的类型)
  • currentPage used by paginator component to switch page. Can be updated at any point.
  • folders contains all folders in the current folder. There are 2 components that use this observable (Types of listing of folder content)
  • files contains all files in the current folder. There are 3 components that use this observable (Types of listing of folder content)

默认视图是没有文件夹的视图,因此我不想进行不必要的 HTTP 调用.

The default view is the one without folders, thus I would like not to make unnecessary HTTP calls.

public currentPage = new ReplaySubject(1);
public folders: Observable<FLFolder[]>;
public files: Observable<FLFile[]>;

constructor(
  activatedRoute: ActivatedRoute,
  folderService: FolderService,
  fileService: FileService,
) {
  // Populate `this.currentPage`
  activatedRoute.queryParams.pipe(
    take(1),
    //  Wait until end of this sync tick. If no emission is made, it will use default in the next tick.
    takeUntil(timer(1, queueScheduler)),
    defaultIfEmpty<Params>({}),
  ).subscribe(query => {
    if (query.page) {
      this.currentPage = +query.page;
    } else {
      this.currentPage = 1;
    }
  });

  /** This observable is internal, only to be used by `folders` and `files` */
  const folderIDAndPage: Observable<[string, number]> = combineLatest(
    activatedRoute.url.pipe(
      switchMap(segments => folderService.getFoldersFromSegments(segments)),
      distinctUntilChanged(),
    ),
    this.currentPage.pipe(
      distinctUntilChanged(),
    ),
  ).pipe(
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );

  this.folders = folderIDAndPage.pipe(
    switchMap(([folderID, page]) => folderService.getFfolders(folderID, page)),
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );

  this.files = folderIDAndPage.pipe(
    switchMap(([folderID, page]) => fileService.getFiles(folderID, page)),
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );
}

当没有订阅 foldersfiles 时,不进行 HTTP.但即使只订阅了其中一个,foldersfiles 都会填​​充(在进行 HTTP 调用时)并同时更新.

When there is no subscribe to either folders, or files, no HTTP are made. But even if one subscribes to only one of them, both folders and files get populated (while making the HTTP call) and updated at the same time.

推荐答案

能否请您在代码中进行以下更改并尝试 -

Can you please make the following change in your code and try -

const getFoldersFromSegments$ = activatedRoute.url.pipe(
  switchMap(segments => folderService.getFoldersFromSegments(segments)),
  distinctUntilChanged(),
  publishReplay(1),
  refCount(),
);

/** This observable is internal, only to be used by `folders` and `files` */
const folderIDAndPage: Observable<[string, number]> = combineLatest(
  getFoldersFromSegments$,
  this.currentPage.pipe(
    distinctUntilChanged(),
  ),
).pipe(
  // Prevent repeating HTTP somehow...
  publishReplay(1),
  refCount(),
);

顺便说一句 - 你已经在 activatedRoute.queryParams observable 上使用了 take(1) ;它将使您的 this.currentPage 仅更改一次.但你说,

BTW - You have used take(1) on activatedRoute.queryParams observable; It will make your this.currentPage to be changed only once. But you said,

可以随时更新

,那岂不是自相矛盾?还是故意的?

, so is it not a contradiction? Or it is intentional?

这篇关于RXJS/Angular 在多个订阅者上防止多个 HTTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆