如何在 Angular 5 中使用 rxJS 存储来自 API 的可观察数据?
How to store observable data from API with rxJS in Angular 5?
我在 angular 中有一个从 API 获取数据的服务,这个数据在很多组件中使用,所以调用 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) 会发生同样的事情。
我想知道是否有 "correct" 方法可以像这样存储数据。我也不认为使用 localstorage 是最好的解决方案,因为它可能包含大量数据,并且随着应用程序的使用它会发生很大变化。
这样做:
服务
// 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 次控制台日志。第一个是空列表,第二个是书。
我在 angular 中有一个从 API 获取数据的服务,这个数据在很多组件中使用,所以调用 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() 部分,但我不知道为什么。
我读过
我想知道是否有 "correct" 方法可以像这样存储数据。我也不认为使用 localstorage 是最好的解决方案,因为它可能包含大量数据,并且随着应用程序的使用它会发生很大变化。
这样做:
服务
// 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 次控制台日志。第一个是空列表,第二个是书。