簡體   English   中英

從返回 mono 的方法創建通量

[英]creating a flux from a method returning mono

我正在學習如何將非反應性代碼更改為反應性代碼。 作為練習的一部分,我使用了這個示例代碼來查找范圍內的素數

public class FindPrime {

    private List<Integer> primes;

    public FindPrime() {
        primes = new ArrayList<>();
    }

    public List<Integer> allPrimes(int low, int high) {
        for (int i = low; i <= high; i++) {
            // skip is the number is 1
            // As 1 is neither prime nor composite
            if (i == 1) continue;

            // if the number is prime add the number to list
            if (isPrime(i) == 1) {
                primes.add(i);
            }
        }
        return primes;
    }

    private int isPrime(int n) {
        // for loop from 2 to sqrt(n)
        for (int i = 2; i <= Math.sqrt(n); i++) {
            // if the number is divisible return -1
            if (n % i == 0) {
                return -1;
            }
        }
        // return 1 if number is prime
        return 1;
    }
}

在將其重寫為反應式代碼時,我開始在生成的列表上使用Flux.fromIterbale以返回通量,但代碼本質上仍然是阻塞的? 特別是isPrime方法。 因此我把它變成了下面的

public Mono<Integer> isPrime(int n) {
    for (int i = 2; i <= Math.sqrt(n); i++) {
        // if the number is divisible return -1
        if (n % i == 0) {
            return Mono.just(-1);
        }
    }
    // return 1 if number is prime
    return Mono.just(1);
}

如果我訪問 Mono, JitteryPrimesEmitter是我有新方法的 class,這對我來說是預期的

JitteryPrimesEmitter emitter = new JitteryPrimesEmitter();
// One Value at a time
int input = 97;
new JitteryPrimesEmitter().isPrime(input)
            .filter(x -> x == 1)
            .subscribe(x -> System.out.println("Got a Prime " + input));

下一步是使用這個isPrime方法發出質數通量,所以我編寫了allPrimes方法如下

public Flux<Integer> allPrimes(int low, int high) {
    return Flux.create((FluxSink<Integer> sink) -> {
        for (int i = low; i <= high; i++) {
            // skip is the number is 1
            // As 1 is neither prime nor composite
            if (i == 1) continue;

            isPrime(i).filter(n -> n == 1)
                    .delayElement(Duration.ofMillis(new Random().nextInt(20) + 1))
                    .doOnNext(m -> System.out.println("Publishing new prime " + m + "for range " + low + "-" + high))
                    .doOnNext(sink::next);
        }
    });
}

隨機延遲是我如何讓它緊張地刺激來自慢速 I/O 上游的數據流。 這不起作用,就好像我用 10、100 作為輸入調用allPrimes我看不到任何結果,這是下游調用

// Flux of values
AtomicInteger sum = new AtomicInteger();
AtomicInteger highest = new AtomicInteger(0);
Flux<Integer> primesFlux = emitter.allPrimes(10, 100);
primesFlux.doOnSubscribe(s -> System.out.println("Subscribed downstream operation to primes flux"));

ConnectableFlux<Integer> primes = primesFlux.publish();
primes.doOnComplete(() -> System.out.println("Sum of Primes = " + sum.get()))
        .subscribe(i -> {
            sum.addAndGet(i);
            System.out.println("Adding emitted prime " + i + " to sum " + sum);
        });

primes.doOnComplete(() -> System.out.println("Highest Prime = " + highest.get()))
        .subscribe(i -> {
            System.out.println("Checking if " + i + " is highest prime in the range 10-100");
            highest.set(i);
        });

primes.connect();
System.out.println("Done Subscribing to Primes Flux");

sumhighest都沒有被填充,我也沒有看到我在下游 Flux 管道中打印的任何消息,我確實看到isPrime mono 方法在從allPrimes方法調用時發出值。

問題是我對allPrimes的實現,這里是固定版本

public Flux<Integer> allPrimes(int low, int high) {
    return Flux.range(low, high - low)
            .flatMap(it ->
                    isPrime(it).flatMap(result ->
                            result == 1 ? Mono.just(it) : Mono.empty()))
            .doOnNext(m -> System.out.println("Publishing new prime " + m + " for range " + low + "-" + high));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM