본문 바로가기
2023년 이전/ReativeX

RxJava, Rxkotlin - defer()

by JeongUPark 2019. 12. 16.
반응형

[출처 - RxJava 프로그래밍 : 리액티브 프로그래밍 기초부터 안드로이드 까지 한번에]

본 글은 'RxJava 프로그래밍 : 리액티브 프로그래밍 기초부터 안드로이드 까지 한번에' 를 학습하면서 정리한 글입니다



마블다이어그램 참고 - http://reactivex.io/RxJava/javadoc/io/reactivex/Flowable.html#defer-java.util.concurrent.Callable-


defer() 함수는 timer() 함수와 비슷하지만 데이터 흐름 생성을 구독자가 subscribe() 함수를 호출할 떄까지 미룰 수 있습니다.

 

마블 다이어 그을 보면 subscribe()할 때마다 값이 발생됩니다.

defer의 원 함수를 보면

    @CheckReturnValue
    @NonNull
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T> Observable<T> defer(Callable<? extends ObservableSource<? extends T>> supplier) {
        ObjectHelper.requireNonNull(supplier, "supplier is null");
        return RxJavaPlugins.onAssembly(new ObservableDefer<T>(supplier));
    }

SchedulerSupport.NONE 이기 때문에 Main thread에서 실행되며, 인자로는 Callable<Observalbe<T>>를 받습니다.

 

간단 예제 code를 보면

Java

import io.reactivex.Observable;

import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.Callable;

public class defer {

    private static Iterator<String> colors = Arrays.asList("1","3","5","6").iterator();
    public static void main(String[] args){
        CommonUtils.exampleStart();
        Callable<Observable<String>> supplier = ()->getObservable();
        Observable<String> source = Observable.defer(supplier);

        source.subscribe(val-> System.out.println("subscriber #1 : "+val));
        source.subscribe(val-> System.out.println("subscriber #2 : "+val));

    }
    private static Observable<String> getObservable(){
        if(colors.hasNext()){
            String color = colors.next();
            return Observable.just(color+"-B", color+"-R",color+"-P");
        }
        return Observable.empty();
    }
}

kotlin

import io.reactivex.Observable
import io.reactivex.rxkotlin.Observables
import java.util.*

private val colors = Arrays.asList("1", "3", "5", "6").iterator()
fun main(args: Array<String>) {
    val supplier = { getObservable() }
    val source = Observable.defer<String>(supplier)
    source.subscribe { `val` -> println("subscriber #1 : $`val`") }
    source.subscribe { `val` -> println("subscriber #2 : $`val`") }

}

private fun getObservable(): Observable<String> {
    if (colors.hasNext()) {
        val color = colors.next()
        return Observable.just("$color-B", "$color-R", "$color-P")
    }
    return Observable.empty()
}

결과는

subscriber #1 : 1-B
subscriber #1 : 1-R
subscriber #1 : 1-P
subscriber #2 : 3-B
subscriber #2 : 3-R
subscriber #2 : 3-P

즉, 위의 

source.subscribe { `val` -> println("subscriber #1 : $`val`") }
source.subscribe { `val` -> println("subscriber #2 : $`val`") }

구독을 2번해서 1과 3이 나타납니다.

 

만약 defer를 사용하지 않는다면

import io.reactivex.Observable;

import java.util.Arrays;
import java.util.Iterator;
import java.util.concurrent.Callable;

public class defer {

    private static Iterator<String> colors = Arrays.asList("1","3","5","6").iterator();
    public static void main(String[] args){
        Observable<String> source = getObservable();
        source.subscribe(val-> System.out.println("subscriber #1 : "+val));
        source.subscribe(val-> System.out.println("subscriber #2 : "+val));
    }
    private static Observable<String> getObservable(){
        if(colors.hasNext()){
            String color = colors.next();
            return Observable.just(color+"-B", color+"-R",color+"-P");
        }
        return Observable.empty();
    }
}

 가 되고 결과는

subscriber #1 : 1-B
subscriber #1 : 1-R
subscriber #1 : 1-P
subscriber #2 : 1-B
subscriber #2 : 1-R
subscriber #2 : 1-P

이렇게 나옵니다. (책에서는 5로 결과가 나오던데... 제가 멀 잘못했는지 1이 나오더라구요 ... 아무튼 요는 defer를 사용하지 않으면 subscribe 하면 동일하게 출력되는 것을 기억하면 좋을것 같습니다.)

반응형

'2023년 이전 > ReativeX' 카테고리의 다른 글

RxJava, RxKotlin - concatMap  (0) 2020.01.14
RxJava, RxKotlin - repeat()  (0) 2019.12.16
RxJava,RxKotlin - interavlRange()  (0) 2019.12.16
RxJava,RxKotlin - range()  (0) 2019.12.04
RxJava, RxKotlin - timer  (0) 2019.11.20