前言
在我看来,操作符的作用就是优雅简洁的替代一部分代码。
举个栗子:
现在有这么一个情况:需要实现一个注册登录的流程,如果不用操作符,代码可能是这样的:
private void login() {
api.login(new LoginRequest())
.subscribeOn(Schedulers.io()) //在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) //回到主线程去处理请求结果
.subscribe(new Consumer<LoginResponse>() {
@Override
public void accept(LoginResponse loginResponse) throws Exception {
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
}
});
}
private void register() {
api.register(new RegisterRequest())
.subscribeOn(Schedulers.io()) //在IO线程进行网络请求
.observeOn(AndroidSchedulers.mainThread()) //回到主线程去处理请求结果
.subscribe(new Consumer<RegisterResponse>() {
@Override
public void accept(RegisterResponse registerResponse) throws Exception {
Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
login(); //注册成功, 调用登录的方法
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
}
});
}
虽然能够实现要求,不过有没有符合RxJava简洁特点的实现方式呢?
因此,操作符应运而生。
正文
全部的操作符可以查看官方文档:http://reactivex.io/documentation/operators.html,这里只是举几个例子:
1. 几个常见的操作符
map
作用:用来把一个事件转换为另一个事件。例如:登陆操作,将数字密码转换为String,并进行加密操作等。
flatmap
作用:转换Observable 为多个Observable与map的区别:
map操作的是一个Observable ,最后更改了这个Observable 的数据类型,而flatMap则是将传过来的数据进行处理,转换为多个Observable,然后发送出去。也就是说flatmap改变了这个Observable ,重新开了一个Observable 。concatMap
作用:与flatmap相似区别:
与flatmap相比,concatMap返回的数据是有序的,而flatmap是无序的。From
作用:from()接收一个集合作为输入,然后每次输出一个元素给subscriber.举个例子:
List s = Arrays.asList(“Java”, “Android”, “Ruby”, “Ios”, “Swift”);
Observable.from(s).subscribe(new Action1() {
@Override
public void call(String s) {
System.out.println(s);
}
});输出结果:
Java
Android
Ruby
Ios
Swift
2. 使用示例:
以上面的例子为例:
1.map
//刚创建的Observable是String类型的
Flowable.just("Hellp Map Operator")
.map(new Function<String, Integer>() {
@Override
public Integer apply(@NonNull String s) throws Exception {
return 2015;//通过第一个map转成Integer
}
}).map(new Function<Integer, String>() {
@Override
public String apply(@NonNull Integer integer) throws Exception {
return String.valueOf(integer);
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
Log.d("TAG", s);
}
});
结果:
2015
2.flatmap
Flowable.create(new FlowableOnSubscribe<Integer>() {
@Override
public void subscribe(FlowableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}, BackpressureStrategy.BUFFER)
.flatMap(new Function<Integer, Publisher<String>>() {
@Override
public Publisher<String> apply(@NonNull Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
list.add("I am value " + integer);
}
return Flowable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS);
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
Log.d("TAG",s);
}
});
结果:
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 2
3.concatMap
与上例相比,结果变为有序输出:
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 1
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 2
D/TAG: I am value 3
D/TAG: I am value 3
D/TAG: I am value 3
总结
操作符的运用还是要看下官方那块怎么写的,找几个例子试一下就明白了。下一篇准备进入实战……顺便开始分析记录我的第一个个人APP的开发过程,感觉单纯讲代码还是没什么意思。RxJava2的最基本用法现在也差不多了,注意点还是在背压那块,不过背压问题也不是经常发生,后面有机会顺便研究下。