如何使用;如有其他",;在RX java链中?
我是RXJava/RXAndroid上的新手。我想实现这个案例:根据RXJava中的某些条件选择不同的方式。 例如,首先,我从网络中获取用户信息,如果这是VIP用户,我将继续从网络中获取更多信息,或者只是在主线程中显示一些信息(断开链)。下面是流程图: 我对此做了一些搜索,只找到“switchIfEmpty”可能会有所帮助。 我编写以下代码:如何使用;如有其他",;在RX java链中?,java,android,rx-java,rx-android,rx-java2,Java,Android,Rx Java,Rx Android,Rx Java2,我是RXJava/RXAndroid上的新手。我想实现这个案例:根据RXJava中的某些条件选择不同的方式。 例如,首先,我从网络中获取用户信息,如果这是VIP用户,我将继续从网络中获取更多信息,或者只是在主线程中显示一些信息(断开链)。下面是流程图: 我对此做了一些搜索,只找到“switchIfEmpty”可能会有所帮助。 我编写以下代码: getUserFromNetwork("userId") .flatMap(new Function<User, O
getUserFromNetwork("userId")
.flatMap(new Function<User, ObservableSource<User>>() {
@Override
public ObservableSource<User> apply(User user) throws Exception {
if(!user.isVip){
//show user info on MainThread!
return Observable.empty();
}else{
return getVipUserFromNetwork("userId");
}
}
}).switchIfEmpty(new ObservableSource<User>() {
@Override
public void subscribe(Observer<? super User> observer) {
//show user info in main thread
//just break the chain for normal user
observer.onComplete();
}
}).doOnNext(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
//show vip user info in main thread
}
}).subscribe();
getUserFromNetwork(“用户ID”)
.flatMap(新函数(){
@凌驾
公共可观测资源应用(用户)引发异常{
如果(!user.isVip){
//在主线程上显示用户信息!
return-Observable.empty();
}否则{
返回getVipUserFromNetwork(“用户ID”);
}
}
}).switchIfEmpty(新的可观察资源(){
@凌驾
public void subscribe(ObserverflatMap()
是一个很好的选择,您可以使用它分割流,但最终流合并在一起(每个分割的可观测流的所有排放都流向主流)。
在代码中,开关ifempty()
是多余的,因为这正是可观察的.empty()
要做的(立即调用onCompleted()
)当然,如果你想让显示发生在主线程上,当然也需要观察者,但无论如何,我认为在流中间处理这不是一个好的实践。
我认为在您的情况下,您可以在单个处理程序中处理(反应)用户发射,因为它非常相似,只需检查它是否为VIP,并相应地显示它。
所以它应该是这样的:
getUserFromNetwork("userId")
.flatMap(new Function<User, ObservableSource<User>>() {
@Override
public ObservableSource<User> apply(User user) throws Exception {
if (!user.isVip) {
return Observable.just(user);
} else {
return getVipUserFromNetwork("userId");
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(user -> {
if (user.isVip){
//display vip user
}else{
//display regular user
}
});
getUserFromNetwork(“用户ID”)
.flatMap(新函数(){
@凌驾
公共可观测资源应用(用户)引发异常{
如果(!user.isVip){
返回可观察的。仅(用户);
}否则{
返回getVipUserFromNetwork(“用户ID”);
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.订阅(用户->{
if(user.isVip){
//显示vip用户
}否则{
//显示普通用户
}
});
在这个方法中,你有一个单一的流流,在流中间没有“副作用”。
如果您处理的是完全不同的(不是这种情况),那么您可以将流拆分为两个分离的流,并对每个流做出不同的反应,这可以通过多播您的getUserFromNetwork()来完成
Observable,并由此创建两个不同的Observable
,一个将继续,例如getVipUserFromNetwork()
,另一个不继续,每个都可以有不同的订户逻辑。(您可以阅读我关于多播的回答)我最近发现了switchIfEmpty操作符,它适合我的需要,可能对某些人有用。Rx对我来说仍然是一种新的思维方式,因此我也愿意听取建议和意见。
让我试着给你另一种思考的方式。正如@yosriz指出的,在随后的onComplete中使用switchIfEmpty是多余的
正如名字所说,switchIfEmpty当基本的一个完成而不发出任何值时,它会切换到另一个可观察的
以下是两种情况:
- 可观察对象发出一个值,然后完成
- 可观察到的数据在不发出值的情况下完成
诀窍是使用空流作为谓词
给定一个用作谓词的基本可观察对象,如果过滤它的发射,可以将switchIfEmpty操作符链接到回退流
在以下代码中,“用户”和“VIP用户”共享相同的界面/类。
即使我使用Java8Lambdas来编写代码,请注意没有if语句
// User Observable, cached so only 1 network call is done
Observable<User> user = getUserFromNetwork("USER_ID").cache();
// This observable is the user's VIP Status as a boolean stream
Observable<Boolean> isVip = user.map(u -> u.isVip() );
这是完整的代码
Observable<User> user = getUserFromNetwork("USER_ID").cache();
Observable<Boolean> isVip = user.map(u -> u.isVip() );
Observable<User> vipUser = isVip
.filter(vip -> vip)
.flatMap(vip -> user.flatMap(usr -> {
return getVipUserFromNetwork(usr.getId());
}));
});
vipUser.switchIfEmpty(user)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(usr -> {
// Handle UI Changes
});
Observable user=getUserFromNetwork(“user_ID”).cache();
可观测isVip=user.map(u->u.isVip());
可观察的振动=isVip
.过滤器(vip->vip)
.flatMap(vip->user.flatMap(usr->{
返回getVipUserFromNetwork(usr.getId());
}));
});
vipUser.switchIfEmpty(用户)
.observeOn(AndroidSchedulers.mainThread())
.订阅(usr->{
//处理UI更改
});
这是您能做的最好的了。您的代码没有问题。
vipUser.switchIfEmpty(user)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(usr -> {
// Logging the class just to understand the outcome
System.out.println("User instanceOf " + usr.getClass());
});
Observable<User> user = getUserFromNetwork("USER_ID").cache();
Observable<Boolean> isVip = user.map(u -> u.isVip() );
Observable<User> vipUser = isVip
.filter(vip -> vip)
.flatMap(vip -> user.flatMap(usr -> {
return getVipUserFromNetwork(usr.getId());
}));
});
vipUser.switchIfEmpty(user)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(usr -> {
// Handle UI Changes
});