如何在 Angular 5 中使用 rxJS 存储来自 API 的可观察数据?

加布里埃尔·比滕古

我有一个从 API 获取数据的 angular 服务,这个数据用于很多组件,所以每次调用 API 来获取相同的数据是一种浪费。

所以我继续尝试使用 BehaviorSubjects 来存储数据。我工作得很好,像这样使用它:

服务:

books = new BehaviorSubject<Book[]>(null);
setBooks(book: Book[]) {
    this.books.next(book);
}
getBooks() {
    this.http.get(...).do(
        (res) => {
            this.setBooks(res.books);
        }
    );
}

组件:

ngOnInit() {
    this.booksService.books.subscribe(
        (books) => {
            // in case the api was never called
            if (books == null) {
                return this.booksService.getBooks().subscribe();
            }
            console.log(books);
            // ...
        }
    );
}

当有书籍时它工作正常,但如果书籍是一个空数组(这是预期的行为之一),程序就会陷入循环,永远调用 api。测试它,我认为它卡在服务调用中的 .do() 部分,但我不知道为什么。

在这里读到BehaviorSubject 并不意味着使用 null 初始值,但就像@estus 建议的那样,使用 ReplaySubject(1) 会发生同样的事情。

我想知道是否有一种“正确”的方式来存储这样的数据。我也不认为使用 localstorage 是最好的解决方案,因为它可能是大量数据,并且随着应用程序的使用而发生很大变化。

猞猁242

这样做:

服务

// init books as BehaviorSubject with an empty array of type Book
books = new BehaviorSubject<Book[]>([]);

setBooks(book: Book[]) {
     this.books.next(book);
}

 // return books as an Observable
 getBooks(): Observable<Book[]> {
     // only if length of array is 0, load from server
     if (this.books.getValue().length === 0) {
          this.loadBooks();
     }

     // return books for subscription even if the array is yet empty. 
     // It‘ll get filled soon.
     return this.books.asObservable();  
  }  

  private loadBooks(): void {
      this.http.get(...).do(
         (res) => {
             this.books.next(res.books);
       } );
  }

TS文件

ngOnInit() {
    this.booksService.getBooks().subscribe(
        (books) => {  
            console.log('books: ', books);
        });
}

这里发生的情况是,您将只加载一次图书列表。图书订阅已建立,图书列表一到达,新列表就会传播给所有订阅者。

所以你应该看到 2 次控制台日志。第一个带有空列表,第二个带有书籍。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用使用 rxJS 的表单控件对来自服务器的可观察加载数据执行过滤?

Angular如何使用rxjs管道从可观察对象中过滤数据

如何在订阅期间从可观察的Angular 5 RxJS中检查NULL结果?

如何基于模式使用RxJS可观察对象过滤数据

稍后如何在 rxjs 可观察流中使用属性?

Angular RxJs可观察流合并数据

如何在rxjs 5中测试使用定时间隔返回可观察值的函数?

如何退订可观察的RxJS 5?

Angular 11 - 如何使用服务传递可观察的数据

如何使用可观察的 rxJS 过滤 json

如何在Angular 5中使用jaxb和rest api正确检索数据?

如何使用本地存储来存储来自API的数据

如何在RXJS中使用可观察变量来转换数组?

在Angular中使用可观察的存储和组件输入

Angular / RxJS如何使用可观察管道生成ajax调用层次结构,但返回单个响应?

如何在 Angular 5 中使用 combineLatest 和 takeUntil rxjs 运算符

如何在Angular服务中使用RxJS处理多个api调用?

如何在 Angular2 中使用 RxJS 与 HATEOAS API 交互?

Angular / RxJS:同步可观察

使用Angular 2显示来自JSON的数据-可观察和异步

如何在 ngrx 效果中使用 ngrx 存储?我需要来自商店的数据来进行 api 调用

如何“存储”来自api的数据

将MergeMap与从另一个可观察到的数据数组一起使用-RxJs Angular

在Angular2中使用RxJS链接可观察对象

如何在反应中使用来自 api (json) 的数据

RxJs-可观察-如何从JSON对象获取数据

如何在RxJs 5中将主题转换为可观察对象

如何在Angular / RxJS中合并两个可观察对象?

如何在Angular 6中使用新的RXJS 6管道/贴图返回解析数据?