是否有一个与BehaviorSubject 等效的东西,不需要初始值并且能够提供当前值?

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

Mic*_*l D 0

怎么样

src = new BehaviorSubject<any>(null);
obs$ = src.asObservable.pipe(filter(value => !!value));
Run Code Online (Sandbox Code Playgroud)

既然您说发送到源的所有值都将有效undefinedfilter则管道将仅过滤初始默认值null。这样您就不必if在每个订阅中进行检查,并且仍然可以保持同步getValue()功能。