| 방식 | 한계 |
|---|---|
| 콜백(callback) | 결과 도착 시 실행할 함수를 넘김. 여러 단계를 엮으면 깊게 중첩되어 콜백 헬 — 가독성·에러 전파가 무너짐 |
Future<T> |
즉시 반환되지만 get()이 블로킹(우발적 블로킹), 지연 평가(lazy) 없음, 다중 값(0..N) 표현이 어려움, 에러 처리 빈약 |
Publisher를 감싸 새 Publisher를 만든다 → 체인이 곧 처리 파이프라인subscribe()): 연산자를 엮어도 즉시 실행되지 않고, subscribe() 시점에 전체 체인이 동작 → 선언과 실행의 분리(지연 평가)Mono/Flux에서 — 2단계)java.util.concurrent.Flow로 표준 라이브러리에 편입 (RxJava·Reactor·R2DBC 등이 이 규약을 구현) public interface Publisher<T> {
void subscribe(Subscriber<? super T> s); // 구독 시작점 (데이터 생산자)
}
public interface Subscriber<T> {
void onSubscribe(Subscription s); // 구독 확립 — 여기서 request로 수요를 건다
void onNext(T t); // 데이터 도착 (0..N회)
void onError(Throwable t); // 에러로 종료 (터미널)
void onComplete(); // 정상 종료 (터미널)
}
public interface Subscription {
void request(long n); // 배압: 구독자가 받을 수 있는 개수(demand)를 요청
void cancel(); // 구독 취소
}
// Processor는 구독자이면서 생산자 — 중간 변환 단계
public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {}
onSubscribe onNext* (onComplete | onError)?
onSubscribe 1회 → onNext 0회 이상 → 종료 신호(onComplete 또는 onError)는 최대 1회Subscription.request(n): 구독자가 “지금 n개까지 받을 수 있다”고 수요(demand)를 명시적으로 요청하고, 생산자는 그 수요를 넘겨 onNext를 보내지 않는다request(n)