【问题标题】:Get last value from incomplete observable从不完整的 observable 中获取最后一个值
【发布时间】:2016-10-26 19:53:09
【问题描述】:

有一个不完整的 observable 可以有或没有 n 个值的重放。我想从中获取最后一个值 - 如果还没有,则只获取下一个值。

这适用于first()take(1) (example) 的第一个可用值:

possiblyReplayedIncomplteObservable.first().toPromise().then(val => ...);

但对于最后一个值,last()takeLast(1) 都等待可观察到的完成 - 这里不是理想的行为。

如何解决?有专门的运营商吗?

【问题讨论】:

  • 你不能使用另一个重放的 observable - 使用相同的源 - 具有单个重放值而不是 N 个值吗?这就是您正在寻找的行为,对吧?

标签: rxjs observable rxjs5


【解决方案1】:

我为ReplaySubject(2) 提供了一个解决方案,它“排空”序列以获取最新元素,如果序列为空,则只需获取最后一个元素,但是,它很麻烦并且不能很好地扩展(例如,如果你决定将回放大小增加到 3)。然后我记得回放/行为主题在通过管道传输时往往难以管理。最简单的解决方案是创建一个“影子”序列并将您的 ReplaySubject 导入其中(而不是通过对您的 ReplaySubject 进行转换/操作来创建它),因此:

var subject$ = new Rx.ReplaySubject(3);
var lastValue$ = new Rx.ReplaySubject(1);
subject$.subscribe(lastValue$); // short hand for subject$.subscribe(v => lastValue$.next(v))

lastValue$.take(1).toPromise().then(...);

========== 旧解决方案,忽略 ReplaySubject(2) =================

看完下面的评论,正确的代码是:

Rx.Observable.combineLatest(possiblyReplayedIncomplteObservable).take(1).subscribe(...)

而不是

Rx.Observable.combineLatest(possiblyReplayedIncomplteObservable).subscribe(...)

这是因为承诺是“一次性”可观察的。我认为toPromise() 代码仅在完成时才解析结果。

take(1) 不会影响您的原始流,因为它在 combineLatest 创建的新流上运行。

实际上,最简单的方法是:

possiblyReplayedIncomplteObservable.take(1).toPromise().then(...)

【讨论】:

  • 谢谢。 combineLatest 将是一个很好的解决方案,但我遇到了问题。它返回一个数组,并且可以轻松修复。但它也会创建不完整的 observable,toPromise 也不能正常工作 (see here)。
  • 可悲的是,它看起来并不那么简单。 take(1) 将从重播中获取第一个值(这里是“二”而不是“三”plnkr.co/edit/MzrwhL1A2YEA0wApfKRy)。所以在这方面和possiblyReplayedIncomplteObservable.take(1)没有区别。
  • 哎呀,这是一个replaySubject。调查一下
  • 但我很困惑,你说“如果还没有,则获取最后一个值或下一个值”,那么问题出在哪里?或者,为什么它是 ReplaySubject(2)?
  • 如果 observable 不为空,我希望此时的最后一个可用值 (three)。或者,如果没有值,则只需等待第一个可用值(one,如果 toPromise 在值被推送到主题之前出现)。希望这个描述足够清楚。
猜你喜欢
  • 1970-01-01
  • 2020-05-28
  • 2021-11-25
  • 2021-08-28
  • 1970-01-01
  • 2019-03-09
  • 2023-03-07
  • 2020-05-04
  • 2020-07-26
相关资源
最近更新 更多