理解为可以控制流程的方法。非常强大而且复杂。
看中文翻译文档: https://www.gitbook.com/book/mcxiaoke/rxdocs/details 虽然文档是Rx1.x的,但是操作符部分和Rxjava2内容相差还是不大的,可以进行观看。
操作符分类有十三种:
| 名称 | 解析 |
|---|---|
| 创建操作 | 用于创建Observable的操作符 |
| 变换操作 | 这些操作符可用于对Observable发射的数据进行变换 |
| 过滤操作 | 这些操作符用于从Observable发射的数据中进行选择 |
| 组合操作 | 组合操作符用于将多个Observable组合成一个单一的Observable |
| 错误处理 | 这些操作符用于从错误通知中恢复 |
| 辅助操作 | 一组用于处理Observable的操作符 |
| 条件和布尔操作 | 用于单个或多个数据项,也可用于Observable |
| 算术和聚合操作 | 用于整个数据序列 |
| 异步操作 | 单独的 rxjava-async 模块,它们用于将同步对象转换为Observable |
| 连接操作 | 一些有精确可控的订阅行为的特殊Observable |
| 转换操作 | 只有一个To,将Observable转换为其它的对象或数据结构 |
| 阻塞操作 | 阻塞Observable的操作符 |
| 字符串操作 | 一些用于处理字符串序列和流的特殊操作符 |
几种主要的需求: - 直接创建一个Observable(创建操作) - 组合多个Observable(组合操作) - 对Observable发射的数据执行变换操作(变换操作) - 从Observable发射的数据中取特定的值(过滤操作) - 转发Observable的部分值(条件/布尔/过滤操作) - 对Observable发射的数据序列求值(算术/聚合操作)
因为操作符太多了,所以每种操作符记录一点。创建操作符在基本使用的时候有说到了,本次是变换操作符
顾名思义,变换操作符就是用来变换的,变换什么呢? 没错就是类型。
| 操作符 | 解析 |
|---|---|
| buffer() | 缓存,可以简单的理解为缓存,它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个 |
| map() | 对序列的每一项都应用一个函数来变换Observable发射的数据序列 |
| flatMap() , concatMap() , flatMapIterable() | 将Observable发射的数据集合变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable |
| switchMap() | 将Observable发射的数据集合变换为Observables集合,然后只发射这些Observables最近发射的数据 |
| scan() | 对Observable发射的每一项数据应用一个函数,然后按顺序依次发射每一个值 |
| groupBy() | 将Observable分拆为Observable集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据 |
| buffer() | 它定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个 |
| window() | 定期将来自Observable的数据分拆成一些Observable窗口,然后发射这些窗口,而不是每次发射一项 |
| cast() | 在发射之前强制将Observable发射的所有数据转换为指定类型 |
这个操作符的意思官方翻译过来是这样子说的:
对Observable发射的每一项数据应用一个函数,执行变换操作
是不是一脸懵逼,好吧。其实我也是。其实大白话的意思就是:
把Observable的数据经过转换,返回转换后的数据。
这样子估计你也不懂,看个栗子��,map后面的Function有两个泛型参数,第一个是输入的类型,第二个是转换后输出返回的类型,可以看到apply方法要返回的是第二个参数的类型。
Observable.just(userParm) .map(new Function<UserParm, Login>() { @Override public Login apply(UserParm userParm) throws Exception { //进行网络请求登录 Login login = api.loginCall(userParm).execute().body(); return login; } }) .subscribeOn(Schedulers.io()) //网络请求是io操作,需要在线程中执行 .observeOn(AndroidSchedulers.mainThread()) //结果需要更新ui就要在主线程中操作 .subscribe(new Consumer<Login>() { @Override public void accept(Login login) throws Exception { //onNext } });api为:
//登录Call @POST("mobile/user/login") Call<Login> loginCall(@Body UserParm userParm);理解为: Observable发射了啥出去,变换之后 还是返回 Observable,知识发射的啥变成了转换之后的啥。
看个栗子��:
/** * 登录 * @param name 用户名 * @param pass 密码 * @return 返回登录成功的token */ PRivate void getUserInfo(String name,String pass){ final UserParm userParm = new UserParm(name,pass); //Function的第二个泛型一定是ObservableSource类型,要转换的类型在ObservableSource里面 Observable.just(userParm).flatMap(new Function<UserParm, ObservableSource<Login>>() { @Override public ObservableSource<Login> apply(UserParm userParm) throws Exception { //返回的是ObservableSource //登录 return api.login(userParm); } }).flatMap(new Function<Login, ObservableSource<UserProfile>>() { @Override public ObservableSource<UserProfile> apply(Login login) throws Exception { //获取用户信息 return api.getUserProfile(login.getData().getToken()); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<UserProfile>() { @Override public void accept(UserProfile userProfile) throws Exception { //onNext tvResult.setText(userProfile.getData().getUser().getName()); } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { //onError } }, new Action() { @Override public void run() throws Exception { //onComplete } }); }使用和flatMap是一样的,有一点不同,就是有新的数据发来的时候,之前的就会取消掉。 可以应用在 多次操作的时候,避免之前的操作慢,后来的操作快,导致前面的数据覆盖了后面的新数据。
缓存发射的数据为一个list,到观察者的时候参数就是一个list。
/** * 测试缓存 */ private void testBuffer() { Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e) throws Exception { for(int i=0; i<10 ;i++){ e.onNext(i+""); } e.onComplete(); } }) .buffer(500,TimeUnit.MILLISECONDS) //缓存500毫秒内发射的数据 .subscribe(new Consumer<List<String>>() { @Override public void accept(List<String> strings) throws Exception { //这里参数就为list,缓存了 500毫秒内发射的String Log.e(TAG, "accept: "+strings.size()); } }); }还有其他的操作符自行测试啦。
新闻热点
疑难解答