[英]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");
sum
和highest
都沒有被填充,我也沒有看到我在下游 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.