@@ -5,6 +5,86 @@ RxJava详解(上)
55
66现在` RxJava ` 变的越来越流行了,很多项目中都使用了它。特别是大神` JakeWharton ` 等的加入,以及` RxBinding、Retrofit、RxLifecycle ` 等众多项目的,然开发越来越方便,但是上手比较难,不过一旦你入门后你就会发现真是太棒了。
77
8+
9+ 在介绍` RxJava ` 之前,感觉有必要说一下什么是函数响应式编程(` FRP ` )?
10+
11+ 函数响应式编程(` FRP ` )为解决现代编程问题提供了全新的视角。一旦理解它,可以极大地简化你的项目,特别是处理嵌套回调的异步事件,复杂的列表过滤和变换,或者时间相关问题,而且` RxJava ` 是响应式编程的一个具体实现。
12+
13+ 这里以一个真实的例子来开始讲解函数响应式编程怎么提高我们代码的可读性。我们的任务是通过查询` GitHub ` 的` API ` , 首先获取用户列表,然后请求每个用户的详细信息。这个过程包括两个` web ` 服务端点:
14+ ` https://api.github.com/users ` -获取用户列表;` https://api.github.com/users/{username} ` -获取特定用户的详细信息,例如` https://api.github.com/users/mutexkid ` 。
15+
16+ 普通情况下是这样写的:
17+ ``` java
18+ // The "Nested Callbacks" Way
19+ public void fetchUserDetails() {
20+ // first, request the users...
21+ mService. requestUsers(new Callback<GithubUsersResponse > () {
22+ @Override
23+ public void success (final GithubUsersResponse githubUsersResponse ,
24+ final Response response ) {
25+ Timber . i(TAG , " Request Users request completed" );
26+ final synchronized List<GithubUserDetail > githubUserDetails = new ArrayList<GithubUserDetail > ();
27+ // next, loop over each item in the response
28+ for (GithubUserDetail githubUserDetail : githubUsersResponse) {
29+ // request a detail object for that user
30+ mService. requestUserDetails(githubUserDetail. mLogin,
31+ new Callback<GithubUserDetail > () {
32+ @Override
33+ public void success (GithubUserDetail githubUserDetail ,
34+ Response response ) {
35+ Log . i(" User Detail request completed for user : " + githubUserDetail. mLogin);
36+ githubUserDetails. add(githubUserDetail);
37+ if (githubUserDetails. size() == githubUsersResponse. mGithubUsers. size()) {
38+ // we've downloaded'em all - notify all who are interested!
39+ mBus. post(new UserDetailsLoadedCompleteEvent (githubUserDetails));
40+ }
41+ }
42+
43+ @Override
44+ public void failure (RetrofitError error ) {
45+ Log . e(TAG , " Request User Detail Failed!!!!" , error);
46+ }
47+ });
48+ }
49+ }
50+
51+ @Override
52+ public void failure (RetrofitError error ) {
53+ Log . e(TAG , " Request User Failed!!!!" , error);
54+ }
55+ });
56+ }
57+ ```
58+
59+ 尽管这不是最差的代码-至少它是异步的,因此在等待每个请求完成的时候不会阻塞-但由于代码复杂(增加更多层次的回调代码复杂度将呈指数级增长)因此远非理想的代码。
60+ 当我们不可避免要修改代码时(在前面的` web service ` 调用中,我们依赖前一次的回调状态,因此它不适用于模块化或者修改要传递给下一个回调的数据)也远非容易的工作。
61+ 我们亲切的称这种情况为“回调地狱”。
62+
63+ 而通过` RxJava ` 的方式:
64+ ``` java
65+ public void rxFetchUserDetails() {
66+ // request the users
67+ mService. rxRequestUsers(). concatMap(Observable :: from)
68+ .concatMap((GithubUser githubUser) - >
69+ // request the details for each user
70+ mService. rxRequestUserDetails(githubUser. mLogin)
71+ )
72+ // accumulate them as a list
73+ .toList()
74+ // define which threads information will be passed on
75+ .subscribeOn(Schedulers . newThread())
76+ .observeOn(AndroidSchedulers . mainThread())
77+ // post them on an eventbus
78+ .subscribe(githubUserDetails - > {
79+ EventBus . getDefault(). post(new UserDetailsLoadedCompleteEvent (githubUserDetails));
80+ });
81+ }
82+ ```
83+
84+ 如你所见,使用函数响应式编程模型我们完全摆脱了回调,并最终得到了更短小的程序。让我们从函数响应式编程的基本定义开始慢慢解释到底发生了什么,并逐渐理解上面的代码,这些代码托管在` GitHub ` 上面。
85+
86+ 从根本上讲,函数响应式编程是在观察者模式的基础上,增加对` Observables ` 发送的数据流进行操纵和变换的功能。
87+
888` RxJava ` 简介
989---
1090
0 commit comments