Files
java-examples/docs/RxJava.md
2025-03-12 10:43:35 +09:00

238 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
### RxJava란?
RxJava(ReactX for Java)는 **반응형 프로그래밍(Reactive Programming)** 을 Java에서 구현할 수 있도록 만든 라이브러리야. 비동기 데이터 흐름을 다루기 쉽게 만들어주고, 함수형 스타일의 연산자를 통해 데이터를 조작할 수 있게 해.
---
### 왜 RxJava를 사용할까?
Java에서 비동기 작업을 하려면 **`Thread`**, **`Executor`**, **`Future`**, **`Callback`** 같은 것들을 써야 하는데, 이 방식들은 코드가 복잡해지고 가독성이 떨어지는 단점이 있어.
RxJava는 이를 더 **선언적으로** 작성할 수 있도록 해주고, 다음과 같은 장점을 제공해:
1. **비동기 처리** `Observable`을 사용하여 비동기적으로 데이터를 생성하고 소비할 수 있어.
2. **함수형 조합** `map`, `filter`, `flatMap` 등의 연산자를 사용해 데이터를 변환하고 조작할 수 있어.
3. **스트림 기반 처리** 데이터가 하나씩 처리되는 것이 아니라 스트림으로 들어오는 데이터를 반응형으로 처리할 수 있어.
4. **에러 처리** `onError` 핸들링을 통해 예외를 쉽게 관리할 수 있어.
5. **백프레셔(Backpressure) 지원** 소비자가 데이터를 처리할 수 없을 때 과부하를 방지할 수 있어.
---
### RxJava의 기본 개념
#### 1. `Observable`과 `Observer`
RxJava에서 가장 중요한 개념은 **`Observable(발행자)`** 와 **`Observer(구독자)`** 야.
- **Observable**: 데이터를 발행하는 역할
- **Observer**: 데이터를 구독해서 처리하는 역할
```java
import io.reactivex.rxjava3.core.Observable;
public class RxJavaExample {
public static void main(String[] args) {
// Observable 생성 (데이터 발행자)
Observable<String> observable = Observable.just("Hello", "RxJava");
// Observer(구독자) 정의
observable.subscribe(System.out::println);
}
}
```
출력:
```
Hello
RxJava
```
---
#### 2. `map`을 이용한 데이터 변환
`map` 연산자를 사용하면 데이터를 변환할 수 있어.
```java
Observable.just(1, 2, 3)
.map(num -> num * 10) // 데이터를 10배 증가
.subscribe(System.out::println);
```
출력:
```
10
20
30
```
---
#### 3. `flatMap`을 이용한 비동기 작업
`flatMap`은 비동기 작업을 수행하고 여러 개의 데이터를 반환할 때 유용해.
```java
Observable.just("Hello")
.flatMap(str -> Observable.fromArray(str.split("")))
.subscribe(System.out::println);
```
출력:
```
H
e
l
l
o
```
---
#### 4. `onError`를 활용한 에러 처리
RxJava는 `onError`를 활용하여 에러를 잡아낼 수 있어.
```java
Observable.just(5, 2, 0)
.map(num -> 10 / num) // 0으로 나누면 예외 발생
.onErrorReturnItem(-1) // 예외 발생 시 기본값 반환
.subscribe(System.out::println);
```
출력:
```
2
5
-1
```
---
### 결론
RxJava는 비동기 프로그래밍을 보다 직관적이고 선언적으로 작성할 수 있도록 도와주는 라이브러리야.
- `Observable`을 사용하여 데이터를 발행하고, `Observer`로 이를 구독할 수 있어.
- `map`, `flatMap`, `filter` 등의 연산자를 사용해 데이터를 변환할 수 있어.
- `onErrorReturnItem` 같은 방식으로 예외 처리를 쉽게 할 수 있어.
비동기 처리, API 호출, 이벤트 스트림 처리 등 다양한 곳에서 활용될 수 있기 때문에, 필요에 따라 적용해보면 좋아!
---
## RxJava의 주요 클래스 및 메서드 정리
RxJava에는 다양한 클래스를 통해 **비동기 데이터 흐름을 처리**할 수 있도록 도와줘. 핵심 클래스들을 정리하고, 각 클래스별 주요 메서드를 표로 정리할게.
---
## 1. 주요 클래스 소개
### (1) `Observable<T>`
- **핵심 역할:** 데이터를 발행하는 기본적인 클래스. **N개의 데이터를 발행**할 수 있어.
- **특징:** 하나 이상의 `Observer`가 구독할 수 있으며, **onNext, onError, onComplete** 이벤트를 제공해.
### (2) `Observer<T>`
- **핵심 역할:** `Observable`이 발행하는 데이터를 **구독(Subscribe)** 하고 처리하는 클래스.
- **주요 메서드:**
- `onNext(T item)`: 새로운 데이터가 발행될 때 호출됨.
- `onError(Throwable e)`: 오류 발생 시 호출됨.
- `onComplete()`: 모든 데이터가 정상적으로 발행 완료되면 호출됨.
### (3) `Single<T>`
- **핵심 역할:** **오직 하나의 데이터** 혹은 **에러만**을 발행하는 클래스.
- **사용 예:** 네트워크 요청 결과(예: 로그인 API 응답).
- **특징:** `onSuccess(T item)`, `onError(Throwable e)` 이벤트를 제공.
### (4) `Maybe<T>`
- **핵심 역할:** 데이터가 **있을 수도 있고 없을 수도 있는** 경우 사용.
- **사용 예:** 로컬 캐시에서 데이터를 불러올 때.
- **특징:** `onSuccess`, `onError`, `onComplete` 이벤트 제공.
### (5) `Completable`
- **핵심 역할:** 데이터를 발행하지 않고, **완료 여부만** 전달하는 클래스.
- **사용 예:** 데이터 저장, 파일 다운로드 완료 이벤트.
- **특징:** `onComplete()`, `onError(Throwable e)` 이벤트 제공.
### (6) `Flowable<T>`
- **핵심 역할:** `Observable`과 유사하지만 **백프레셔(Backpressure) 지원**이 필요한 경우 사용.
- **사용 예:** 많은 양의 데이터를 빠르게 발행할 때(예: 실시간 로그 스트림).
---
## 2. 클래스별 주요 메서드 정리
각 클래스별 주요 메서드를 표로 정리하면 다음과 같아.
### (1) `Observable<T>`의 주요 메서드
| 메서드 | 설명 |
|--------|------|
| `just(T...)` | 지정한 데이터를 순차적으로 발행 |
| `fromArray(T[])` | 배열 데이터를 순차적으로 발행 |
| `fromIterable(Iterable<T>)` | 리스트 데이터를 순차적으로 발행 |
| `create(ObservableOnSubscribe<T>)` | 직접 `onNext`, `onError`, `onComplete` 이벤트를 발생시키도록 정의 |
| `map(Function<T, R>)` | 데이터를 변환 |
| `flatMap(Function<T, Observable<R>>)` | 비동기적으로 데이터를 변환 |
| `filter(Predicate<T>)` | 조건을 만족하는 데이터만 발행 |
| `debounce(long, TimeUnit)` | 짧은 시간 내에 연속으로 발행되는 데이터 중 마지막 데이터만 발행 |
| `merge(Observable<T>...)` | 여러 개의 `Observable`을 합침 |
| `zip(Observable<T1>, Observable<T2>, BiFunction<T1, T2, R>)` | 두 개의 `Observable`을 결합하여 새로운 데이터 발행 |
| `onErrorReturn(Function<Throwable, T>)` | 에러 발생 시 기본값을 반환 |
| `subscribe(Observer<T>)` | 데이터를 구독 |
---
### (2) `Single<T>`의 주요 메서드
| 메서드 | 설명 |
|--------|------|
| `just(T)` | 단일 데이터를 발행 |
| `fromCallable(Callable<T>)` | 데이터 생성 작업을 비동기적으로 수행 |
| `map(Function<T, R>)` | 데이터를 변환 |
| `flatMap(Function<T, Single<R>>)` | 비동기적으로 데이터를 변환 |
| `subscribe(SingleObserver<T>)` | 데이터를 구독 |
---
### (3) `Maybe<T>`의 주요 메서드
| 메서드 | 설명 |
|--------|------|
| `just(T)` | 단일 데이터를 발행 |
| `empty()` | 아무 데이터도 발행하지 않음 |
| `fromCallable(Callable<T>)` | 데이터 생성 작업을 비동기적으로 수행 |
| `map(Function<T, R>)` | 데이터를 변환 |
| `flatMap(Function<T, Maybe<R>>)` | 비동기적으로 데이터를 변환 |
| `subscribe(MaybeObserver<T>)` | 데이터를 구독 |
---
### (4) `Completable`의 주요 메서드
| 메서드 | 설명 |
|--------|------|
| `complete()` | 작업을 성공적으로 완료 |
| `fromRunnable(Runnable)` | 실행 후 완료 이벤트를 발행 |
| `fromCallable(Callable<Void>)` | 실행 후 완료 이벤트를 발행 |
| `subscribe(CompletableObserver)` | 완료 이벤트를 구독 |
---
### (5) `Flowable<T>`의 주요 메서드
| 메서드 | 설명 |
|--------|------|
| `just(T...)` | 지정한 데이터를 순차적으로 발행 |
| `fromArray(T[])` | 배열 데이터를 순차적으로 발행 |
| `fromIterable(Iterable<T>)` | 리스트 데이터를 순차적으로 발행 |
| `create(FlowableOnSubscribe<T>, BackpressureStrategy)` | 직접 데이터를 발행하며 백프레셔 전략 설정 |
| `map(Function<T, R>)` | 데이터를 변환 |
| `flatMap(Function<T, Flowable<R>>)` | 비동기적으로 데이터를 변환 |
| `filter(Predicate<T>)` | 조건을 만족하는 데이터만 발행 |
| `subscribe(Subscriber<T>)` | 데이터를 구독 |
---
## 3. 마무리
RxJava에는 다양한 클래스가 있고, 각각의 역할이 있어:
- `Observable` → 일반적인 비동기 데이터 스트림 처리
- `Single` → 하나의 데이터만 반환 (예: 네트워크 응답)
- `Maybe` → 데이터가 있을 수도, 없을 수도 있음
- `Completable` → 데이터 없이 완료 이벤트만 전달
- `Flowable` → 백프레셔가 필요한 경우 사용
각 클래스에는 `map`, `flatMap`, `filter` 같은 연산자가 존재해서 **데이터를 조작하고 가공**하는 게 가능해.
특히 `Observable``just`, `fromArray`, `merge` 등을 이용해 다양한 방식으로 데이터를 발행할 수 있어.
필요한 기능에 맞게 적절한 클래스를 선택해서 사용하면 RxJava를 효과적으로 활용할 수 있을 거야!