Quarkus/Mutiny 中是否需要递归?
Is recursion necessary in Quarkus/Mutiny?
我正在尝试使用 Redis 的 scan 功能,该功能需要调用直到返回的光标为“0”。
这种方法可行,但感觉过于复杂 - 有没有不用递归的方法?
Uni<Object> callScanRecursively(String cursorNum, List<String> results) {
List<String> args = new ArrayList<>(List.of(cursorNum, "MATCH", "*"));
return reactiveRedisClient.scan(args)
.onItem()
.transformToUni(item -> {
List<String> keysList = new ArrayList<>();
item.get(1).forEach(k -> {
keysList.add(k.toString());
});
results.addAll(keysList);
if (item.get(0).toString().equals("0")) {
return Uni.createFrom().item(results);
} else {
String nextCursorNum = item.get(0).toString();
return callScanRecursively(nextCursorNum, results);
}
}
);
}
List<String> results = new ArrayList<>();
String startingCursorRedis = "0";
callScanRecursively(startingCursorRedis, results)
.subscribe()
.with(item ->
LOGGER.info(item)
);
您可以使用 MultiRepeat
通过 Uni
发射器收集 ReactiveRedisClient#scan
结果,同时给定条件 response.get(0).toString().equals("0")
仍未满足:
单一发射器
Multi<String> callScan(String initialCursor) {
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.<AtomicReference<String>, List<String>>uni(
() -> cursorReference,
(state, emitter) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.subscribe()
.with(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
java.util.List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
emitter.complete(keysList);
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}
大学
如果您不需要对发出的项目进行更多控制,甚至更简单:
Multi<String> callScan(String initialCursor) {
ReactiveRedisClientImpl reactiveRedisClient = new ReactiveRedisClientImpl();
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.uni(
() -> cursorReference,
(state) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.invoke(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
})
.map(response -> {
List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
return keysList;
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}
我正在尝试使用 Redis 的 scan 功能,该功能需要调用直到返回的光标为“0”。
这种方法可行,但感觉过于复杂 - 有没有不用递归的方法?
Uni<Object> callScanRecursively(String cursorNum, List<String> results) {
List<String> args = new ArrayList<>(List.of(cursorNum, "MATCH", "*"));
return reactiveRedisClient.scan(args)
.onItem()
.transformToUni(item -> {
List<String> keysList = new ArrayList<>();
item.get(1).forEach(k -> {
keysList.add(k.toString());
});
results.addAll(keysList);
if (item.get(0).toString().equals("0")) {
return Uni.createFrom().item(results);
} else {
String nextCursorNum = item.get(0).toString();
return callScanRecursively(nextCursorNum, results);
}
}
);
}
List<String> results = new ArrayList<>();
String startingCursorRedis = "0";
callScanRecursively(startingCursorRedis, results)
.subscribe()
.with(item ->
LOGGER.info(item)
);
您可以使用 MultiRepeat
通过 Uni
发射器收集 ReactiveRedisClient#scan
结果,同时给定条件 response.get(0).toString().equals("0")
仍未满足:
单一发射器
Multi<String> callScan(String initialCursor) {
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.<AtomicReference<String>, List<String>>uni(
() -> cursorReference,
(state, emitter) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.subscribe()
.with(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
java.util.List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
emitter.complete(keysList);
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}
大学
如果您不需要对发出的项目进行更多控制,甚至更简单:
Multi<String> callScan(String initialCursor) {
ReactiveRedisClientImpl reactiveRedisClient = new ReactiveRedisClientImpl();
final AtomicReference<String> cursorReference = new AtomicReference<>(initialCursor);
return Multi.createBy()
.repeating()
.uni(
() -> cursorReference,
(state) -> reactiveRedisClient.scan(List.of(state.get(), "MATCH", "*"))
.invoke(response -> {
if (response.get(0).toString().equals("0")) {
cursorReference.set(null);
} else {
state.set(response.get(0).toString());
}
})
.map(response -> {
List<String> keysList = new ArrayList<>();
response.get(1).forEach(k -> keysList.add(k.toString()));
return keysList;
})
)
.whilst(o -> cursorReference.get() != null)
.flatMap(l -> Multi.createFrom().iterable(l));
}