【问题标题】:Combining observables结合可观察物
【发布时间】:2012-04-22 05:49:09
【问题描述】:

我有两个 observable:LoadLocal 和 LoadServer。 LoadLocal 从本地源加载并返回一个元素,LoadServer 从服务器获取它。我想将它们组合成另一个可观察的:加载。我想让Load从LoadLocal中获取元素,如果它为null,我想从LoadServer中返回元素。关于如何做到这一点的任何想法?

谢谢


真实场景详情:

// loadLocal(id) gives me an observable that returns an asset from a local source
Func<Guid, IObservable<IAsset>> loadLocal = Observable.ToAsync<Guid, IAsset>(id => GetLocalAsset(id));

var svcClient = new ServiceClient<IDataService>();
var svc = Observable.FromAsyncPattern<Request, Response>(svcClient.BeginInvoke, svcClient.EndInvoke);

// calling loadServer(id) gives me an observable that returns an asset from a server
var loadServer = id => from response in svc(new Request(id)) select response.Asset;

// so at this point i can call loadServer(id).Subscribe() to get an asset with specified id from the server, or I can call loadLocal(id).Subscribe() to get it from local source.
// however I want another observable that combines the two so I can do: load(id).Subscribe() that gets the asset from loadLocal(id) and if it is null it gets it from loadServer(id)
var load = ???

以下几乎给了我想要的结果,但是 loadLocal(id) 和 loadServer(id) 都运行了。如果 loadLocal(id) 返回一个元素,我不希望 loadServer(id) 运行。

var load = id => loadLocal(id).Zip(loadServer(id), (local, server) => local ?? server);

【问题讨论】:

  • 当您使用IObservable 时,您不会“获取”值。相反,当创建新值时,您会被调用(通过Subscribe)。我真的不明白你的问题,所以也许你可以提供一些关于你的 observables 以及它们如何一起玩的更多细节?
  • 用真实场景的细节更新了问题。
  • 我找到了一个解决方案: var load = id => from localAsset in loadLocal(id) from asset in (localAsset != null ? Observable.Return(localAsset) : loadServer(id)) select asset;
  • @Pking,那么您应该将其发布为答案并接受它。

标签: c# system.reactive


【解决方案1】:

这个怎么样:

loadLocal(id)
    .Where(x => x != null)
    .Concat(Observable.Defer(() => loadServer(id)))
    .Take(1);

【讨论】:

  • 谢谢,除了我在原始帖子的 cmets 中提到的解决方案之外,这也有效。
【解决方案2】:

大概是这样的吧?

var load = LoadLocal.Zip(LoadServer, (local, server) => local ?? server);

【讨论】:

  • 谢谢,试过了,效果很好。但是,即使 LoadLocal 返回元素,它仍然会尝试从服务器 (LoadServer) 获取元素(如果可以在本地获取元素,那么重点是避免不必要的往返服务器)。
  • @Pking,实际上我不确定我是否理解您要做什么... Martin 的评论是正确的:您不会从可观察对象中获取值。
  • 用真实场景的细节更新了问题。我很有可能以错误的方式处理问题。 “fetch”指的是 observable 本身所做的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
相关资源
最近更新 更多