use*_*903 5 subject observable behaviorsubject angular
寻找相同的功能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 before it has been set!");
return this._value;
}
constructor()
{
this.replaySubject = new ReplaySubject<T>(1);
}
public next(value: T)
{
this._canGetValue = true;
this._value = value;
this.replaySubject.next(value);
}
public asObservable()
{
return this.replaySubject.asObservable();
}
public canGetValue()
{
return this._canGetValue;
}
}
Run Code Online (Sandbox Code Playgroud)
最初,我指定扩展了该类,但是,正如 crowmagnumb 在他对行为主体初始值 null? 的ReplaySubject回答中指出的那样。,以某种方式覆盖它会破坏它。相反,我决定包装并公开所需的方法和字段。nextReplaySubjectReplaySubject
怎么样
src = new BehaviorSubject<any>(null);
obs$ = src.asObservable.pipe(filter(value => !!value));
Run Code Online (Sandbox Code Playgroud)
既然您说发送到源的所有值都将有效undefined,filter则管道将仅过滤初始默认值null。这样您就不必if在每个订阅中进行检查,并且仍然可以保持同步getValue()功能。
| 归档时间: |
|
| 查看次数: |
3313 次 |
| 最近记录: |