2 Вопрос: что делает Mono.defer ()?

вопрос создан в Thu, May 2, 2019 12:00 AM

Я встречал Mono.defer () в каком-то коде Spring Webflux

Я посмотрел метод в документах, но не понимаю объяснения:

"Создайте провайдера Mono, который будет предоставлять целевой Mono для подписки для каждого подписчика в нисходящем направлении "

пожалуйста, я мог бы дать объяснение и пример. Есть ли место с кучей примеров кода Reactor (их модульные тесты?), На которые я мог бы сослаться.

спасибо

    
0
  1. Вы проверили Javadoc? Большинство методов Flux /Monos содержат диаграмму того, как он работает с реактивным потоком.
    2019-05-02 16: 52: 48Z
  2. да, приведенная выше цитата взята из javadoc. Я лично нахожу язык трудным для понимания; некоторые примеры тривального кода помогут мне. Я клонирую проект активной зоны реактора и собираюсь просмотреть модульные тесты, чтобы увидеть, поможет ли это.
    2019-05-03 07: 27: 44Z
  3. комбинация кода примера, ссылки и комментария, которые Obxable RxJava должны быть заменены на Mono или Flux, когда чтение его примеров помогло мне.
    2019-05-03 09: 21: 41Z
2 ответа                              2                         

Это немного упрощает, но концептуально источники Reactor либо ленивы, либо нетерпеливы. Ожидается, что более продвинутые, такие как HTTP-запрос, будут лениво оцениваться. С другой стороны, стремятся самые простые, такие как Mono.just или Flux.fromIterable.

Я имею в виду, что вызов Mono.just(System.currentTimeMillis()) немедленно вызовет метод currentTimeMillis() и захватит результат. Указанный результат испускается только Mono после его подписки. Многократная подписка также не меняет значение:

Mono<Long> clock = Mono.just(System.currentTimeMillis());
//time == t0

Thread.sleep(10_000);
//time == t10
clock.block(); //we use block for demonstration purposes, returns t0

Thread.sleep(7_000);
//time == t17
clock.block(); //we re-subscribe to clock, still returns t0

Оператор defer предназначен для того, чтобы сделать этот источник ленивым, переоценивая содержание лямбды каждый раз, когда появляется новый подписчик :

Mono<Long> clock = Mono.defer(() -> Mono.just(System.currentTimeMillis()));
//time == t0

Thread.sleep(10_000);
//time == t10
clock.block(); //invoked currentTimeMillis() here and returns t10

Thread.sleep(7_000);
//time == t17
clock.block(); //invoke currentTimeMillis() once again here and returns t17
    
1
2019-05-03 14: 48: 00Z

с простыми словами если вы видите в первом представлении, это похоже на Mono.just (), но это не так. когда вы запускаете Mono.just (), он сразу же создает Observable (Mono) и повторно использует его, но когда вы используете defer, он не создает его сразу, он создает новый Observable при каждой подписке.

Один вариант использования, чтобы увидеть разницу

    int a = 5;
@Override
public void run(String... args) throws Exception {

    Mono<Integer> monoJust = Mono.just(a);
    Mono<Integer> monoDefer = Mono.defer(() -> Mono.just(a));

    monoJust.subscribe(integer1 -> System.out.println(integer1));
    monoDefer.subscribe(integer1 -> System.out.println(integer1));

    a = 7;
    monoJust.subscribe(integer1 -> System.out.println(integer1));
    monoDefer.subscribe(integer1 -> System.out.println(integer1));
}

печать: 5,5,5,7 р>

если вы видите, что mono.just сразу же создал наблюдаемое, и оно не изменится, даже если значение изменилось, но отложенное создание наблюдаемого в подписке позволяет работать с текущим значением onsubscribe

    
2
2019-05-03 08: 24: 46Z
  1. спасибо @RichardKollcaku, поэтому моно имеет снимок состояния своего базового объекта, и defer говорит, что текущее состояние каждый раз, когда вызывается подписка, вызывается
    2019-05-03 08: 36: 03Z
  2. Ваше объяснение не совсем верно. Нет ничего такого, как «создать новую наблюдаемую». Просто и отложите создание Observable. Mono.just возвращает значение для каждой подписки, а Mono.defer оценивает функцию поставщика.
    2019-05-03 08: 39: 10Z
  3. я не разговариваю Наблюдаемый как объект, но Наблюдаемый как логика. Mono en En Observable. Mono. Просто создайте новый Observable, это означает, что создайте новый Mono @htn
    2019-05-03 08: 41: 42Z
  4. @ jrender не может быть применен к моментальному снимку состояния в случае Mono.just(). В этом примере он использует примитивный тип, поэтому результат не изменяется, но если вы используете объект (например, список) и изменяете его (добавляете новое значение) между двумя подписками, у вас будет 2 разных результата, но это все тот же объект.
    2019-05-03 08: 49: 52Z
  5. 2019-05-03 08: 54: 29Z
источник размещен Вот