深入浅出RxJava—操作符

来源:互联网 发布:纯阳谢云流捏脸数据 编辑:程序博客网 时间:2024/04/30 09:11

原文链接
参考文章

本篇文章将重点介绍RxJava中的操作符,RxJava的强大性就来于它所定义的操作符。
假如我们现在有这样一个接口,返回一个网站地址list集合,并将集合数据进行打印,基于上一篇文章,我们可能写出这样的代码:
先贴出query方法代码:
查询将输入地址:
1
        query().subscribe(new Action1<List<String>>() {
2
            @Override
3
            public void call(List<String> list) {
4
5
                for (String s : list) {
6
                    Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
7
                }
8
            }
9
        });
这段代码使我们丢失了变换数据流的能力,一但要更改数据只能在subscribe 总进行,那你会说可以使用map操作符
这样的代码依旧要使用集合遍历的方式才能获取到每一个元素。幸运的是RxJava提供了另外一个方法from,它接受一个集合作为输入,然后每次输出一个元素给subscriber。
1
        query().subscribe(new Action1<List<String>>() {
2
            @Override
3
            public void call(List<String> list) {
4
                Observable.from(list).subscribe(new Action1<String>() {
5
                    @Override
6
                    public void call(String s) {
7
                        Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
8
                    }
9
                });
10
            }
11
        });
这样虽然去掉了遍历循环,但是代码看起来依然很凌乱,多个嵌套的subscription看起来很臃肿且不好维护。
救星来了,它就是flatMap,Observable.flatMap()接受一个Observable 为输入参数,同时输出另外一个Observable,直接上代码:
理解flatMap的关键点在于,flatMap输出的Observable的泛型类型正是我们在subscriber 想要接受的。

继续,我们我们根据query查询的网址打印出其对应的title,要怎么做呢?先上getTilte(String title)的代码:
1
    private Observable<String> getTitle(String url) {
2
3
        Observable<String> observable = Observable.empty();
4
5
        switch (url) {
6
            case "baidu":
7
                observable = Observable.just("百度");
8
                break;
9
            case "youku":
10
                observable = Observable.just("优酷");
11
                break;
12
            case "iqiyi":
13
                observable = Observable.just("爱奇艺");
14
                break;
15
            case "sohu":
16
                observable = Observable.just("搜狐");
17
                break;
18
            case "":
19
                observable = Observable.just(null);
20
                break;
21
        }
22
23
        return observable;
24
    }
上代码:

我们可以一直使用flatMap操作符来变换数据直到是subscriber想要的数据类型为止。在测试代码中有些返回的数据是null ,那我们怎么过滤这些数据呢?另一个操作符闪亮登场,它就是filter,
1
        query().flatMap(new Func1<List<String>, Observable<String>>() {
2
            @Override
3
            public Observable<String> call(List<String> list) {
4
                return Observable.from(list);
5
            }
6
        }).flatMap(new Func1<String, Observable<String>>() {
7
            @Override
8
            public Observable<String> call(String s) {
9
                return getTitle(s);
10
            }
11
        }).filter(new Func1<String, Boolean>() {
12
            @Override
13
            public Boolean call(String title) {
14
                return title != null;
15
            }
16
        }).subscribe(new Action1<String>() {
17
            @Override
18
            public void call(String s) {
19
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
20
            }
21
        });
filter()输出和输入相同的元素,并且会过滤掉那些不满足检查条件的。这样,就将title为null的值给过滤掉了。现在输出的是4个结果了,那如果我们只想要前两个结果怎么办呢? 这就引入了另外一个操作符了,take,上代码:
take()输出最多指定数量的结果。另外,我们我们在最终输出结果之前还想对数据做一些操作,别如将title保存起来,这就要使用另一个操作符了,doOnNext:
1
        query().flatMap(new Func1<List<String>, Observable<String>>() {
2
            @Override
3
            public Observable<String> call(List<String> list) {
4
                return Observable.from(list);
5
            }
6
        }).flatMap(new Func1<String, Observable<String>>() {
7
            @Override
8
            public Observable<String> call(String s) {
9
                return getTitle(s);
10
            }
11
        }).filter(new Func1<String, Boolean>() {
12
            @Override
13
            public Boolean call(String title) {
14
                return title != null;
15
            }
16
        }).take(2).doOnNext(new Action1<String>() {
17
            @Override
18
            public void call(String s) {
19
                saveTitle(s);
20
            }
21
        }).subscribe(new Action1<String>() {
22
            @Override
23
            public void call(String s) {
24
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
25
            }
26
        });
doOnNext()允许我们在每次输出一个元素之前做一些额外的事情,比如这里的保存标题。
本篇主要讲了这么几个操作符,RxJava提供的操作符实在是很强大的,还可以自定义操作符。将一系列的操作符链接起来就可以完成复杂的逻辑。代码被分解成一系列可以组合的片段。这就是响应式函数编程的魅力。用的越多,就会越多的改变你的编程思维。



原创粉丝点击