rx java_你会在实际工作中使用 rxjava 吗?

RxJava中包括丰富的操作符,这里结合实际的场景来谈谈Rx中常用的操作符的使用。

我们在项目中使用最多的就是Retrofit配合RxJava的网络请求处理。但是项目中可能会有一些特殊的需求或设计不合理的接口,需要客户端对接口的调用进行高精度的控制,这时候RxJava的操作符就派上大用场了。

场景一:使用flatMap注册成功后自动登录

假设现在有一个这样的需求:服务端有注册和登录两个接口,但是这两个接口的功能是分离的,注册成功并不会自动登录,需要客户端再进行调用登录接口才可以。

现在我们来分析下这个场景:需要在注册成功后调用登录,在没有使用RxJava的时候可能会这样解决:在注册登录的回调里再写一个登录,我来用伪代码来模拟下:

Api.register(username, password, new CallBack() {

public void onSuccess(){

Api.login(username, password, new CallBack() {

public void onSuccess() {

//登陆成功

}

});

}

});

这里没有涉及到异常情况的处理,这样是可以实现这样的功能,但是很容易陷入缩进地狱,假设现在有需要在登录前通过网络获取一下ip,那就是又要加一层回调。这样代码不美观且不利于维护,我们来看看用Rx是怎样处理的吧:

Api.register(account, password)

.flatMap(new Function, ObservableSource>() {

@Override

public ObservableSource apply(@NonNull BizResponse response) throws Exception {

// 注册成功后执行登录方法

return Api.login(account, password);

}

})

.subscribe(new Consumer() {

@Override

public void accept(@NonNull UserLoginResponse userLoginResponse) throws Exception {

// 成功

}

}, new Consumer() {

@Override

public void accept(@NonNull Throwable throwable) throws Exception {

// 失败

}

});

这里我们用到了一个操作符flatMap,它和map很像,不一样的是map从一个对象转化为另一个对象,而flatMap可以从一个对象转化为一个Observable对象,后续继续对它进行操作。

这样咋一看麻烦了很多,其实分析一下其实这段代码更容易维护——如果需要增加新的操作,比如异步获取ip,就在flatMap之前加入这个操作,flatMap之后的代码不用动;而且有统一的异常入口——里面任何的异常都会在第二个Consumer中捕获。

场景二:使用compose简化代码

在网络请求中一般会加入这两句话

observable.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread());

在io线程执行网络操作,在主线程执行ui操作。但是每个observable都要写这两句话,能不能简化呢?当然是可以的。这就要用到compose操作符。我们可以在RxUtils中定义一个这样的方法:

/**

* io线程执行,主线程观察

* .compose(RxUtils.applySchedulers())

*/

public static ObservableTransformer applySchedulers() {

return new ObservableTransformer() {

@Override

public ObservableSource apply(@NonNull Observable observable) {

return observable.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread());

}

};

}

使用的时候在subscribe方法之前加入.compose(RxUtils.applySchedulers())就可以了。

当然,这个方法可以增加更多的逻辑,比如判断一个接口返回的数据是否异常,一般服务端会返回一个状态来判断:

/*** 增加了统一的判断逻辑*/

public static ObservableTransformer applyBizSchedulers() {

return new ObservableTransformer() {

@Override

public ObservableSource apply(@NonNull Observable observable) {

return observable

.map(new Function() {

@Override

public T apply(@NonNull final T t) throws Exception {

if (t.getRcode() != 0) {

throw new RuntimeException(t.getRmsg());

}

return t;

}

})

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread());

}

};

}

上面的例子中,如果返回的code不是0,则直接抛出异常,统一在 Consumer中处理。

场景三:使用zip对并发的请求做处理

现在有一个这样的需求:假设在用户页面,不仅要显示用户的普通信息,还要显示用户的资金信息。这两个信息分别对应的两个接口,同时访问两个接口,当两个信息都获取成功的时候才算成功,如果有一个没获取成功则算失败,需要重新获取。

如果没有rx,这个需求实现起来非常复杂,只能按照先后顺序获取,这样就会增加加载的时间。

我们可以通过RxJava中的zip来实现:

Observable.zip(Api.getNewsList(), Api.getBanner(), new BiFunction, BizResponse>, Pair, List>>() {

@Override

public Pair, List> apply(List news, List banner) throws Exception {

return Pair.create(news, banner);

}

})

.compose(RxUtils.applySchedulers())

.subscribe(...)

场景四:debounce控制频率

假设有一个搜索框,在输入后自动搜索输入的内容。咋一看这个需求很简单,只需要监听EditText的输入事件,然后调用搜索接口就可以。但是如果用户输入过快,就会造成接口的频繁调用。有什么好的方式控制接口的调用频率呢?debounce就可以解决。

RxTextView.textChanges(search)

.debounce(1, TimeUnit.SECONDS)

通过这段代码,EditText的textChange事件会在输入间隔大于一秒时调用,这样如果用户因正在输入造成的接口调用频繁的问题就解决了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值