rx.Observable<T>表示的是一个值的流序列。它是你会用到所有的时间的抽象。因为这些值经常出现在较宽的时间范围内,所以我们倾向于将一个Observable看作一个事件流。如果你环顾四周,你会发现许多流的例子:

  • 用户界面事件

  • 通过网络传输的字节

  • 网上购物的新订单

  • 在社交媒体网站上发表文章

如果你想将Observable<T>与你所熟悉的东西比较,那么 Iterable<T>就是最相似的抽象了,就像从 Iterable<T> 中创建Iterator<T>,Observable<T>可以有0到一个无穷大的T类型的值。Iterator (迭代器)在生成无限序列时非常有效;例如,所有自然数,如这里所示:

class NaturalNumbersIterator implements Iterator<BigInteger> {
    private BigInteger current = BigInteger.ZERO;
    public boolean hasNext() {
        return true;
    }
    @Override
    public BigInteger next() {
        current = current.add(BigInteger.ONE);
        return current;
    }
}

另一个相似之处是,Iterator (迭代器)本身可以向它的客户机发出信号,表示它没有更多的项目可以迭代了(稍后再详细说明)。然而,相似之处就在这里。Observable本质上是基于push(推)的,这意味着它决定什么时候产生值。另一方面,迭代器是空闲的,直到有人真正请求next()方法获取下一项。传统上,这种行为在Observable中不可能的——在某个时间点,客户端代码可以订阅一个Observable,当Observable感觉它应该发出一个值时,我们就会得到通知。它随时都可能发生。在这本书的后面,我们将会研究226页的“背压”;这是一种机制,使订阅者可以在某些情况下控制Observable的发送的速度。

此外,Observable可以产生任意数量的事件。显然,这听起来就像经典的观察者模式,也称为发布-订阅(如果你想了解更多,看设计模式:可重用面向对象软件的元素由Erich Gamma和Richard Helm[addison - wesley])然而,就像迭代器不需要得到底层集合的支持(见NaturalNum bersIterator),Observable不一定要代表一系列事件。是时候看看一些Observable的例子了:

  • Observable<Tweet> tweets:tweet(推文)可能是事件流中最明显的例子。我们马上就会明白,任何社交媒体网站上的状态更新都是不断被创造出来的,当然也可以用一连串的事件来表示。另外,与迭代器不同的是,当数据对我们有用时,我们不能手动pull(拉取)数据。Observable必须在数据出现时推送数据。
  • Observable<Double> temperature:温度Observable也非常相似;它产生了设备的一些温度的值 并将其推送给订阅用户。tweets和温度Observable是无穷无尽的future事件流的例子。
  • Observable<Customer> customers:Observable<Customer>所代表的东西依赖于上下文。很可能它会返回一个客户列表,数据可能是来自数据库查询。它可以是零、几个甚至数千个条目,可能是惰性加载。或者,这个Observable 可以代表一个客户登录到您的系统的流。客户端编程模型不会改变,无论Observable<Customer>是如何实现的。
  • Observable<HttpResponse> response:Observable<HttpResponse>,换句话说,直到它中止,很可能只产生一个事件(值)。这个值会在将来出现,并将被推到客户机代码。要阅读响应,我们必须订阅它。
  • Observable<Void> completionCallback:最后,还有一个古怪的Observable<Void>。从技术上讲,Observable可以发射零项并终止。在这种情况下,我们不关心可观察到的实际值类型,因为它们永远不会出现。

实际上, Observable<T>实际上可以产生三种类型的事件:

  • 类型T的值,即在Observable 的泛型上声明的类型

  • Completion事件

  • Error事件

响应式拓展额规范明确的指出每一个Observable发送任意数量的值,可选地跟踪Completion或Error(但不是二者兼具)。严格的Rx设计准则定义如下:OnNext *(OnCompleted | OnError)?------- OnNext代表一个新的事件。有趣的是,这种正则表达式规则的任何组合都是有效的:

  • OnNext OnCompleted:Observable 释放一个值并优雅地终止。这当Observable代表一个对外部系统的请求并且 我们也网一个单一的返回值的情况下,可以使用这种方式。
  • OnNext + OnCompleted:Observable会在它终止之前发出多个事件。这可以表示从数据库中读取一个列表,并以单个值的方式接收每条记录。另一个例子是跟踪一些完成长时间运行的流程的进度。
  • OnNext+:无限的事件列表,如社交媒体网站上的评论或某些组件的状态更新(例如,鼠标移动和ping请求)。这条流是无限的,必须在空中消费掉。
  • OnCompleted or OnError only:这种Observable只能正常或异常终止。OnError另外包装了一个导致流终止的Throwable。Errors是通过事件发出的,而不是使用标准的throw语句。
  • OnNext+ OnError:流可能成功地发出一个或多个事件,但最终会失败。通常,这意味着一个流应该是无限的,但同时由于致命错误而失败。考虑一个网络数据包的序列,它可以交付事件数小时,但在某个时间点由于连接丢失而中断。

onError通知常有趣。因为Observable 的异步性质,简单地抛出异常没有什么意义。相反,我们必须将错误传递给感兴趣的人,可能跨越线程,并在一段时间内。OnError是一种特殊类型的事件,它以泛函的方式封装异常。您可以在第243页上阅读更多关于“错误处理”的异常。

此外,您还可以实现一个不发出任何事件(包括Completion或Error)的Observable 。这样的Observable 对于测试的目的是非常有用的,例如,用于测试超时。

results matching ""

    No results matching ""