RxJava как дождаться выполнения запроса в RxJava и во время выполнения не вызывать его снова?

Вопрос в следующем, как дождаться выполнения запроса в RxJava и во время выполнения не вызывать его снова?

Или же например вызывать, но обрабатывать результат только последнего, а предыдущих игнорировать.

Предпочтительнее конечно варианты решения методами самой RxJava. Спасибо за любую помощь!


Ответы (1 шт):

Автор решения: Alex_Skvortsov

Наиболее простые два решения:

  1. Решение средствами RxJava, метод switchMap

    Без использования switchMap (метод flatMap):

    @Test
    public void flatMap() throws Exception {
        final List<String> items = Lists.newArrayList("a", "b", "c", "d", "e", "f");
    
        final TestScheduler scheduler = new TestScheduler();
    
        Observable.from(items)
                .flatMap( s -> {
                    final int delay = new Random().nextInt(10);
                    return Observable.just(s + "x")
                            .delay(delay, TimeUnit.SECONDS, scheduler);
                })
                .toList()
                .doOnNext(System.out::println)
                .subscribe();
    
        scheduler.advanceTimeBy(1, TimeUnit.MINUTES);
    }
    

    Вывод в результате запуска: [cx, ex, fx, bx, dx, ax]

    С использованием switchMap (вместо метода flatMap):

    @Test
    public void flatMap() throws Exception {
        final List<String> items = Lists.newArrayList("a", "b", "c", "d", "e", "f");
    
        final TestScheduler scheduler = new TestScheduler();
    
        Observable.from(items)
                .switchMap( s -> {
                    final int delay = new Random().nextInt(10);
                    return Observable.just(s + "x")
                            .delay(delay, TimeUnit.SECONDS, scheduler);
                })
                .toList()
                .doOnNext(System.out::println)
                .subscribe();
    
        scheduler.advanceTimeBy(1, TimeUnit.MINUTES);
    }
    

    Вывод в результате запуска: [fx]

    Необходимо отметить, что в данном случае выполняться будет только последний запрос, предыдущие при повторном вызове будут прерываться.

  2. Решение "костыльное", своими силами.

    Изначальный код тот же.

    @Test
    public void flatMap() throws Exception {
        final List<String> items = Lists.newArrayList("a", "b", "c", "d", "e", "f");
    
        final TestScheduler scheduler = new TestScheduler();
    
        bool flag = false;
    
        Observable.from(items)
                .filter(s -> { return !flag } )
                .doOnNext(s -> {flag = true })
                .flatMap( s -> {
                    final int delay = new Random().nextInt(10);
                    return Observable.just(s + "x")
                            .delay(delay, TimeUnit.SECONDS, scheduler);
                })
                .toList()
                .doOnNext(System.out::println)
                .doOnComplete( { flag = false })
                .subscribe();
    
        scheduler.advanceTimeBy(1, TimeUnit.MINUTES);
    }
    

    Вывод в результате запуска: [ax]

    Второй способ не начнет исполнение нового запроса, если еще выполняется старый.

Код написан на коленке, если видите опечатки / ошибки - комментируйте и исправляйте)

→ Ссылка