我一直在寻找那些3:
主题,行为主体和重播主题.我想使用它们,知道何时以及为什么,使用它们有什么好处,虽然我已阅读文档,观看教程和搜索谷歌,但我没有对此有任何意义.
那他们的目的是什么?一个真实的案例将是非常感谢它甚至不必编码.
我更喜欢一个干净的解释,而不只是"a + b => c,你订阅了......"
谢谢
javascript reactive-programming rxjs angular2-observables angular
我正在更新我们的软件替换所有承诺(和其他毛茸茸的垃圾)的可观察性.为了确保我遵循最佳实践,我做了一个快速googlearch并注意到在某些情况下,建议的语法是实例,而在其他情况下,示例执行工厂调用.
const byInstance = new Observable(_ => { ... });
const byFactory = Rx.Observable.create(_ => { ... });
Run Code Online (Sandbox Code Playgroud)
我很好奇实际差异是什么.它们是否可以互换?它是一种较旧/较新的语法/方法吗?它与框架有关吗?当然,这是首选的(在不存在主张,有争议等的情况下).
寻找相同的功能BehaviorSubject但不必提供初始值。
在从我加载数据的任何源加载数据之前,我经常需要订阅一个主题。我还需要在订阅后立即触发订阅,当且仅当next()之前在该主题上调用过该订阅,并且我希望它向我显示最后发出的值,并且能够在任何时间点同步获取当前值,类似到value的领域BehaviorSubject。
这是我尝试过的:
Subject,但它不会在订阅后立即发出旧值,BehaviorSubject而且我无法检索当前值。ReplaySubject缓冲区大小为 1,但这也不允许检索当前值。BehaviorSubject.create()而不是new BehaviorSubject<Whatever>(null),但这在调用时不会执行任何操作next()。不会发出任何值,并且订阅代码永远不会触发。BehaviorSubject但.pipe(skip(1)).subscribe如果我在调用后运行此代码,next()那么我会丢失旧的但有效的值,只有在next再次调用后才触发。我想到的唯一解决方案是扩展该类,ReplaySubject为当前值添加一个私有字段(该字段在next()调用时设置),并添加一个 getter 来检索它。
我总是希望这些值被定义并且有效,所以我不明白为什么我必须为我BehaviourSubject特别希望不是未定义/空并相应地显式定义它们的对象类型提供默认的空/未定义值,并且然后在每个订阅中编写一个 if 语句,以在每次发出新值时检查它是否有效。
我也不明白为什么每次我在加载数据之前订阅该主题时,它必须发出该空值并导致每个订阅无缘无故地触发。
那么我错过了什么替代方案吗?
编辑:到目前为止,我的问题的答案似乎是不,没有等效的。因此,我为任何正在寻找相同行为的人提供解决方法:
import { ReplaySubject } from 'rxjs';
export class SensibleSubject<T>
{
private replaySubject: ReplaySubject<T>;
private _canGetValue = false;
private _value!: T;
public get value()
{
if (!this._canGetValue)
throw new Error("Attempted to retrieve value …Run Code Online (Sandbox Code Playgroud) 我有一个角度服务,可以从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);
}
);
}
Run Code Online (Sandbox Code Playgroud)
组件:
ngOnInit() {
this.booksService.books.subscribe(
(books) => {
// in case the api was never called
if (books == null) {
return this.booksService.getBooks().subscribe();
}
console.log(books);
// ...
}
);
}
Run Code Online (Sandbox Code Playgroud)
有书籍时,它工作正常,但是如果书籍是一个空数组(这是预期的行为之一),则程序将陷入循环,并永远调用api。测试它,我发现它被卡在服务调用的.do()部分中,但是我不知道为什么。
我在这里读到BehaviorSubject并不是要使用空初始值,而是像建议的@estus一样,使用ReplaySubject(1)也会发生同样的事情。
我想知道是否存在“正确”的方式来存储数据。我也不认为使用localstorage是最好的解决方案,因为它可能会存储大量数据,并且在使用应用程序时会发生很大变化。