如何构建一个服务,该服务获取异步值,但也对该数据执行任务,例如过滤? [英] How to build a service that gets values async but also perfoms tasks on that data, like filtering?

查看:14
本文介绍了如何构建一个服务,该服务获取异步值,但也对该数据执行任务,例如过滤?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一项以根目录提供"的服务:

  • 从 API 获取一次数据
  • 应该处理该数据的映射
  • 应在需要时将该数据提供给其他组件

无需在应用的整个生命周期中重新加载此数据.它仅在用户刷新浏览器时重新加载.所有数据都将在某个时候使用 - 因此对每个 getOneById() 发出 http 请求是没有意义的.在这种情况下,过滤器速度更快.

This data doesn't need to be reloaded throughout the lifecycle of the app. It's only reloaded when the user refreshes the browser. All of the data is going to be used at some point - so it makes no sense to make http requests on each getOneById(). A filter is faster in this case.

服务的模型看起来像这样:

The mockup of the service looks something like this:

export class MyTypeService {
  items: MyType[] = [];
  items$ = new BehaviorSubject<MyType[]>(this.items);

  constructor(private http: HttpClient) { }

  getData(): Subscription {
    return this.http.get<SearchResult>(
      'path'
    ).pipe(
      map((response: any) => {
        this.items = response;
        return this.items;
      }),
      catchError(error => {
        // removed from the question for simplicty
        this.handleError(error);
        return of([]);
      })
    ).subscribe(result => this.items$.next(result));
  }

  getOneById(id: string): MyType|null {
    for (let item of this.items) {
      if (item.id === id) {
        return item;
      }
    }

    return null;
  }
}

现在我迷失了这些问题:

Now I'm lost with these questions:

  • 服务本身是否应该订阅 items$?
    或者是否应该所有成员函数,例如 getOneById() 订阅?
    (这可能意味着,我可以删除 items.
  • 我是否应该在构造函数中调用 getData(),因为在应用程序运行期间我肯定需要这些值?
    或者应该在第一次实际需要值时调用它吗?
  • 如何告诉组件使用 getOneById() 是安全的?
  • Should the service itself subscribe to items$?
    Or should all member functions, like getOneById() subscribe?
    (Which could mean, that I can remove items.
  • Should I call getData() in the constructor, as I definitely need the values during the run of the app?
    Or should it be called the first time the values are actually needed?
  • How can I tell a component, that it's safe to use getOneById()?

推荐答案

你不应该拥有没有 Observable 的项目.像这样的东西应该可以工作,所以当你不需要它时你不会发出 http 请求

You shouldn't have items without Observable at all. Something like this should work so you don't make http request when you dont need it

  itemsSub: BehaviorSubject<any[]> = new BehaviorSubject(null);

  getItems(): Observable<any[]> {
    return this.itemsSub.pipe(mergeMap(items => {
      if (items) {
        return of(items); // Return items if you already have them
      } else {
        // If you don't have them, get them and emit on subject
        return this.http.get().pipe(tap((items) => this.itemsSub.next(items))); 
      }
    }))
  }

  getItemsFiltered() {
    return this.getItems().pipe(filter(items => !!items));
  }

这篇关于如何构建一个服务,该服务获取异步值,但也对该数据执行任务,例如过滤?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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