我正在编写用户界面。在某些操作中,我想知道特定IObservable的最新值。我该怎么知道呢?
这是一个模拟我想要实现的目标的测试。你能帮忙解决一下吗?
var selectedItemOut = new Subject<int?>();
// idea: define some other IObservable or subject here
var getLatest = new Func<int?>(() =>
{
// fix me
return 0;
});
Assert.AreEqual(null, getLatest());
selectedItemOut.OnNext(4);
Assert.AreEqual(4, getLatest());
selectedItemOut.OnNext(5);
Assert.AreEqual(5, getLatest());
selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, getLatest());
答案 0 :(得分:2)
如果你可以改变你的selectedItemOut主题是像Slugart这样的BehaviorSubject那将是最好的(我会将First()更改为Take(1),但那只是我)。如果你不能,那么你需要在函数范围之外创建一个变量。
var selectedItemOut = new Subject<int?>();
// Hold the last result from the OnNext
int? results = null;
// idea: define some other IObservable or subject here
// update var each time OnNext is called
var lastResult = selectedItemOut.Subscribe(i => results = i);
// just a wrapper around the results var.
var getLatest = new Func<int?>(() => results);
Assert.AreEqual(null, getLatest());
selectedItemOut.OnNext(4);
Assert.AreEqual(4, getLatest());
selectedItemOut.OnNext(5);
Assert.AreEqual(5, getLatest());
selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, getLatest());
//Need to tell the observable to stop updating the results var.
lastResultDispose.Dispose();
现在真的你的func只是引用结果var,你需要告诉它何时停止跟踪它。这不是很Rx,因为Rx是关于推送值而你想从中检索一个值。
答案 1 :(得分:2)
如果selectedItemOut可以是BehaviourSubject<int?>
,则可以使用其Value
属性:
var selectedItemOut = new BehaviorSubject<int?>(null);
var getLatest = new Func<int?>(() =>
{
return selectedItemOut.Value;
});
否则CharlesNRice的回答看起来不错,或者您可以使用MostRecent
:
var mostRecent = selectedItemOut.MostRecent(null).GetEnumerator();
var getLatest = new Func<int?>(() =>
{
mostRecent.MoveNext();
return mostRecent.Current;
});
// need to clean up this up
mostRecent.Dispose()
答案 2 :(得分:0)
鉴于您需要初始值(即使它为空),然后是最新值,您可以将BehaviorSubject
与First()
一起使用。有关上下文的更多信息有助于提供更好的解决方案,因为不建议使用First()
。
var selectedItemOut = new BehaviorSubject<int?>(null);
// idea: define some other IObservable or subject here
Assert.AreEqual(null, selectedItemOut.First());
selectedItemOut.OnNext(4);
Assert.AreEqual(4, selectedItemOut.First());
selectedItemOut.OnNext(5);
Assert.AreEqual(5, selectedItemOut.First());
selectedItemOut.OnNext(6);
selectedItemOut.OnNext(7);
Assert.AreEqual(7, selectedItemOut.First());