Observable单一工作如何?

时间:2015-07-17 18:47:05

标签: rx-java observable

当我在一个observable上调用.single()时,它的类型是“Observable<`?>”如果我将它传递给另一种方法,我不相信它有任何意义,知道它已被单独。我不认为我完全理解这是如何工作的。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

如果类型未通过,您可能需要弄清楚为什么签名没有从Observable调用它来进行,或者手动添加。因此,对于Foo类型的Observable

myFooObservable.<Foo>single()

单个作用与limit(1)非常相似,只是如果上游Observable在完成时没有输出正好1项(包括0项),它也会抛出错误。

通常,在设计Observable链时,Observable的使用者应设计为好像他们可以处理零个或多个值。确实,另一种方法不知道将从Observable发出多少东西。如果您希望订阅者只需要输出一个元素,则应该在订阅前将.single()添加到Observable

例如,假设您获得getFoos方法:

Observable<Foo> getFoos();

出于某种原因(可能是图书馆,代码或外星人)你无权访问这个,所以你不知道它会发出多少东西(如果有的话)。如果你想强制执行一件事,你可以这样做:

getFoos().single().subscribe(
    (foo) -> /* Do something with foo */,
    (error) -> /* Oh noes there was an error. Maybe it completed with no output? */);

这会将其限制为只有一件事,如果在没有输出Foo的情况下完成,或者如果它尝试输出第二个Foo,则会抛出错误。

如果getFoos方法在single上提交了Observable,则getFoos的作者应负责:

  1. 设计并测试得足以让它始终只发出一个项目。对于消费者来说可能是最好的方法,API方面,但如果涉及外部因素,这并不总是可行的,例如#2 ......
  2. CLEARLY 文档,它可能并不总是发出单个项目,如果没有,则会引发错误,因此您可以处理该错误。不是我最喜欢的方法,但是在某些事情上(比如网络响应),如果没有发出一个项目,则声明可能会发出错误是有意义的。例如,如果网络流程的任何部分存在问题,Retrofit库可能会抛出RetrofitError个例外(我实际上并不是肯定的,这是明确记录的,但考虑到我很早就发现了它在使用该应用程序时,我认为很容易找到)。他们非常擅长确保特定于网络请求/响应和解析的流程包含在RetrofitError中,因此如果发生某些严重的运行时错误而不是该流程的一部分,它将会失败并崩溃(因为它通常应该在那个例子中,因为那些可能是编程错误或严重的,不可恢复的系统错误。)
  3. 处理single运算符下游的错误本身,可以通过记录然后在没有值的情况下结束时不发送任何内容。就我的API口味而言,这是中间的某个地方。虽然它本身可以处理错误,但是有一些合法的情况让消费者想要处理并从错误中恢复,这就消除了这种能力。例如,我的某个Android应用使用retryretryWhen来确定是否应重试请求,并使用各种错误转换器来应用这些设置以设置不同的错误处理行为。有些请求我只想记录错误并继续。其他我喜欢做指数退避重试...其他我可能想做1或2次立即重试然后放弃。还有一些我可能想直接向用户显示“重试”UX按钮。
  4. 如果他们不满足这3个中的至少1个,我会认为API设计得很差,因为这种行为通常会给消费者带来惊喜。

    由于我不知道您的实际使用案例,因此有些摘要有点抽象,所以如果您有后续问题,我会很乐意澄清其中的个别方面。