[번역] RxJava에서 Operators 재입문 1

[번역] RxJava에서 Operators 재입문 1

Jan 30, 2017. | By: pluulove

본 포스팅은 RxJavaでOperators再入門 その1 포스팅을 번역했습니다.

제 일본어 실력으로 인하여 오역이나 오타가 발생할 수 있습니다.

실제 발표내용에 해당하는 슬라이드와 슬라이드의 일본어 부분만 번역만 번역했다는 점 양해바랍니다.


이 기사는 RxJava Advent Calendar 2016의 10번째 기사입니다.

RxJava Advent Calendar에 참가했지만, 무엇을 쓸지 고민했고, 그러고 보니 나는 느닷없다고 생각되어 Operators을 다시 한번 공부하려고 생각했습니다.

그 첫 번째로는 분량이 많기 때문에 나누려고 생각했기 때문에 총 5회로 나눌 예정입니다.

그럼 첫 번째는 ReactiveX Introduction에 쓰여 있는 Creating Observables, Transforming Observables 두 가지에 대해 살펴보겠습니다.

Creating

주로 새로운 Observable을 생성하는 오퍼레이터

Create

스크래치로 Observable을 만드는 연산자입니다.

Android에서는 비동기 통신에서 자주 보는 것이네요.

사용법은 다음과 같은 느낌입니다.

public class Create {
    public static void main(String[] args) {
        Observable.create(e -> {
            Person person = new Person();
            person.age = 100;
            person.name = "nshiba";
            e.onNext(person);
            e.onComplete();
        }).subscribe(System.out::println);
    }

    private static class Person {
        int age;
        String name;

        @Override
        public String toString() {
            return name + ":" + String.valueOf(age);
        }
    }
}

출력

nshiba:100

onNext에서 값을 전달하고, 종료 시에 onComplete를 부르는 느낌입니다.

또한, 오류의 경우에는 onError를 부릅니다.

Defer

defer 는 실행시키는 Observablesubscribe 할 때 생성하는 오퍼레이터입니다.

일반 create는 그 자리에서 실행하는 Observable을 만들지만, deferObservable의 생성 자체를 지연시킵니다.

Observable observable = Observable.defer(() -> observer -> {
    observer.onNext("test");
    observer.onComplete();
});

// 이 순간 defer 에서 새로운 Observable을 만들 수 있다
observable.subscribe(System.out::println);

Empty/Never/Throw

이러한 Operator들은 한정된 용도로 주로 테스트용으로 사용된다고 생각합니다.

Empty

아무런 값은 없지만, 정상으로 종료하는 Observable을 만듭니다.

onComplete 만 호출됩니다.

Never

아무런 값 없이 종료도 하지 않는 Observable을 만듭니다.

Throw

아무런 값은 없지만, 지정한 에러를 내뱉는 Observable을 만듭니다.

From

다양한 객체를 Observable로 변환합니다.

아마도 목록을 변환하는 경우가 많을 거라고 생각하기 때문에 샘플은 fromArray로 만들어 보았습니다.

int[] nums = new int[] {1, 2, 3, 4, 5};
Observable
        .fromArray(nums)
        .subscribe(ints -> {
            System.out.println("onNext");
            System.out.println(Arrays.toString(ints));
        },
        throwable -> {
            System.out.println("onError");
        },
        () -> {
            System.out.println("onComplete");
        });

출력

onNext
[1, 2, 3, 4, 5]
onComplete

Interval

지정한 일정한 간격으로 정숫값을 출력하는 Observable을 생성합니다.

처음에 어느 정도 지연시킬지의 지정도 가능합니다.

Observable
        .interval(1, TimeUnit.SECONDS)
        .subscribe(System.out::print);

출력

01234567789...

Just

직접 인수로 전달된 객체로 Observable을 생성합니다.

또한, 복수로 전달된 경우는 그만큼 onNext이 호출되어 복수 전달할 경우는 형이 통일되지 않아도 오류가 발생하지 않습니다.

Observable.just(3, 1, 5, 4, "test")
        .subscribe(num -> {
            System.out.println("onNext: " + num);
        }, throwable -> {
            System.out.println("onError");
        }, () -> {
            System.out.println("onComplete");
        });

출력

onNext: 3
onNext: 1
onNext: 5
onNext: 4
onNext: test
onComplete

Range

지정한 범위의 정수를 출력하는 Observable을 생성합니다.

Observable.range(0, 10)
        .subscribe(i -> {
            System.out.println("onNext: " + i);
        }, throwable -> {
            System.out.println("onError");
        }, () -> {
            System.out.println("onComplete");
        });

출력

onNext: 0
onNext: 1
onNext: 2
onNext: 3
onNext: 4
onNext: 5
onNext: 6
onNext: 7
onNext: 8
onNext: 9
onComplete

Repeat

지정한 횟수 반복하는 Observable을 생성합니다.

Observable.just(1, 2, 3, 4, 5)
        .repeat(3)
        .subscribe(i -> {
            System.out.println("onNext: " + i);
        }, throwable -> {
            System.out.println("onError");
        }, () -> {
            System.out.println("onComplete");
        });

출력

onNext: 1
onNext: 2
onNext: 3
onNext: 1
onNext: 2
onNext: 3
onNext: 1
onNext: 2
onNext: 3
onComplete

Start

뭔가 계산한 값 등을 반환시키는 메소드의 반환 값을 출력하는 Observable을 만듭니다.

Create 와 조금 닮은 부분이 있습니다만, 이쪽은 반환 값이 임의의 값이며, onNext, onComplete는 부르지 않는 것입니다.

Observable.fromCallable(() -> {
    String str = "java";
    str += ":" + "RxJava";
    return str;
}).subscribe(System.out::println);

출력

java:RxJava

Timer

지정한 시간만큼 지연 후 값을 출력하는 Observable을 만듭니다.

System.out.println(System.currentTimeMillis());
Observable.timer(3, TimeUnit.SECONDS)
        .subscribe(aLong -> {
            System.out.println(System.currentTimeMillis());
        });

출력

1480975677330
1480975680651

Transforming

Buffer

지정한 간격으로 스트림을 나누어 리스트를 작성하는 오퍼레이터.

Observable.range(1, 5)
        .buffer(3)
        .subscribe(System.out::println);

출력

[1, 2, 3]
[4, 5]

FlatMap

스트림에 들어온 것을 처리하고 새로운 Observable로 합성하는 오퍼레이터.

Observable.just(1, 2, 3)
        .flatMap(i -> Observable.range(i, i * 2))
        .subscribe(System.out::print);

출력

122345345678

GroupBy

스트림을 조건에 따라 그룹으로 나누는 오퍼레이터.

같은 그룹으로 하고 싶은 것에 같은 값을 반환하면 같은 그룹이 됩니다.

Observable.range(1, 10)
        .groupBy(integer -> integer % 3)
        .subscribe(integerIntegerGroupedObservable -> {
            integerIntegerGroupedObservable.toList().subscribe(System.out::println);
        });

출력

[3, 6, 9]
[1, 4, 7, 10]
[2, 5, 8]

Map

스트림에 들어온 값을 변화시킬 수 있는 오퍼레이터.

위의 FlatMap과의 차이는 FlatMapObservable을 반환하고 Map은 값 자체를 반환합니다.

Observable.just(1,2,3)
        .map(i -> i * 10)
        .subscribe(System.out::println);

출력

10
20
30

Scan

리스트에 순차적으로 액세스해 나가는 Operator. 2개씩 액세스해 간다.

처음에는 첫 번째와 두 번째가 인수로 전달되고, 그 이후에는 이전 처리로 반환된 값이 첫 번째 인수·다음 값이 두 번째 인수로 전달된다.

subscribe시에 전달된 값은 요소의 첫 번째 + 반환 값에 전달 된 값.

Observable.range(1, 5)
        .scan((sum, item) -> sum + item)
        .subscribe(System.out::println);

출력

1
3
6
10
15

Window

지정한 간격으로 스트림을 나누어 분할된 스트림으로 새로운 Observable을 만드는 오퍼레이터.

위의 Buffer와 비슷하지만, BufferList<Integer>를 출력하는 반면, WindowObservable<Integer>를 출력한다.

Observable.range(1,5)
        .window(3)
        .subscribe(integerObservable -> {
            integerObservable.toList().subscribe(System.out::println);
        });

출력

[1, 2, 3]
[4, 5]

마지막으로

이런 식으로 다른 것도 할 수 있다면 좋겠습니다.

소스 코드는 공개하고 있습니다 -> nshiba/rx-samples

그리고, 뭔가 잘못된 점 등 있다면 댓글이나 github의 issue 등에 적어 주면 기쁩니다.

comments powered by Disqus

Currnte Pages Tags

Java RxJava

About

Pluu, Android Developer Blog Site

이전 블로그 링크 :네이버 블로그

Using Theme : SOLID SOLID Github

Social Links