首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Quarkus/Mutiny中是否需要递归?

在Quarkus/Mutiny中是否需要递归?
EN

Stack Overflow用户
提问于 2021-11-02 18:05:39
回答 1查看 103关注 0票数 0

我正在尝试使用Redis的scan功能,它需要被调用,直到返回的游标为“0”。

这种方法很有效,但感觉太复杂了--有没有一种不需要递归的方法?

代码语言:javascript
复制
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)
    );
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-10 16:00:00

当给定条件response.get(0).toString().equals("0")仍未满足时,您可以使用MultiRepeat通过Uni发射器收集ReactiveRedisClient#scan结果:

Uni发射器

代码语言:javascript
复制
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));
}

Uni

如果不需要对发出的项进行更多的控制,甚至可以更简单:

代码语言:javascript
复制
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));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69815030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档