当前位置: 首页 > 知识库问答 >
问题:

将顺序Monos转换为Flux

吕英豪
2023-03-14

我有一个Web服务,我想检索树的元素到根节点。我有一个网络流量接口,它在每次调用时返回一个单声道:

public interface WebService {
    Mono<Node> fetchNode(String nodeId);
}

public class Node {
    public String id;
    public String parentId; // null, if parent node
}

让我们假设有一棵树

    1
  2   3
  4   5

我想创建以下方法:

public interface ParentNodeResolver {

    Flux<Node> getNodeChain(String nodeId);
}

这将给我在getNodeChain(5)上一个通量,节点为5,3和1,然后完成。

不幸的是,我不太明白如何按顺序组合Monos,但不阻止它们。使用流量。generate(),我想我需要在每个mono上阻塞,以检查它是否有下一个元素。我发现的其他方法似乎只结合了固定数量的mono,但不是以这种递归方式。

下面是一个示例代码,它可以模拟网络请求,但有一定的延迟。

public class MonoChaining {
    ExecutorService executorService = Executors.newFixedThreadPool(5);

    @Test
    void name() {
        var nodeChain = generateNodeChainFlux("5")
                .collectList()
                .block();
        assertThat(nodeChain).isNotEmpty();
    }

    private Flux<Node> generateNodeChainFlux(String nodeId) {
        //TODO
        return Flux.empty();


    }

    public Mono<Node> getSingleNode(String nodeId) {
        var future =
                CompletableFuture.supplyAsync(() -> {
                    try {
                        Thread.sleep(2000); // Simulate delay
                        if ("5".equals(nodeId)) {
                            return new Node("5", "3");
                        } else if ("3".equals(nodeId)) {
                            return new Node("3", "1");
                        } else if ("1".equals(nodeId)) {
                            return new Node("1", null);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return null;
                }, executorService);

        return Mono.fromFuture(future);
    }


    public static class Node {
        public String id;
        public String parentId;

        public Node(String id, String parentId) {
            this.id = id;
            this.parentId = parentId;
        }
    }
}

有办法找回这个吗?谢谢

共有2个答案

班言
2023-03-14

使用带有flatMap的递归来获取父节点,并使用concat将当前节点附加到生成的flux可能有效。请尝试以下代码:

public Flux<Node> getNodeChain(String nodeId) {
    return fetchNode(nodeId).flatMapMany(node -> {
        if (node.parent != null) {
            Flux<Node> nodeChain = getNodeChain(node.parent);
            return Flux.concat(Flux.just(node), nodeChain);
        }
        return Flux.just(node);
    });
}

这里我使用flatMapManyMono转换为Flux

马魁
2023-03-14

您要查找的操作员是Mono#expand。它用于递归扩展序列。在这里阅读更多。

就你而言:

private Flux<Node> generateNodeChainFlux(String nodeId) {
        return getSingleNode(nodeId).expand(node -> getSingleNode(node.parentId));
    }
 类似资料:
  • 问题内容: 假设我有以下设置 我们知道返回类型B。 当我做的时候 投射输入然后尝试调用吗? 调用上铸造的结果类型? 我发现很难确定,而且总是在谨慎的情况下打上额外的括号(对于可读性来说,这不是一个坏主意,但现在我很好奇) 尽管我看不到这将如何改变行为,但具体参考了。 问题答案: 等价于,即问题中的#2。 要获得#1,您必须编写。 Java语言规范没有在易于理解的摘要中指定运算符优先级。 Sedge

  • 我正在尝试用在3个不同的(单击)之间切换,下面是我的代码, 方法是从另一个SO帖子引用的。 现在单击窗格3->转换将首先显示,然后显示。 现在单击窗格2->过渡将显示,上面2点中提到的问题不再出现。 为什么转换显示,然后在第1和第2点显示实际的窗格?是不透明度设置的原因吗?

  • 如何将按排序顺序转换为而不更改()?我们希望保留和。 将2,3,1添加到将其排序为1,2,3。从创建一个将具有2,3,1的顺序。中的和方法也将具有2,3,1的顺序。我猜这与的实现有关。

  • 问题内容: 我有一个字节数组,其中数组中的数据实际上是短数据。字节按小端顺序排列: 3、1,-48、0,-15、0、36、1 转换为短值时会导致: 259、208、241、292 Java中是否有一种简单的方法可以将字节值转换为相应的短值?我可以编写一个仅占用每个高字节并将其移位8位,或与低字节进行移位的循环,但这会降低性能。 问题答案: 使用java.nio.ByteBuffer可以指定所需的字

  • 问题内容: 当我转换到元素的顺序发生变化,由字符排序。 考虑以下示例: 我的问题是 为什么会这样呢? 如何进行设置操作(尤其是“设置差异”)而不丢失初始顺序? 问题答案: 是无序的数据结构。 不要使用,而是: 请注意,的顺序b无关紧要,因此它可以是可迭代的,但是应该是支持O(1)成员资格测试的可迭代。 编辑:上面的答案假定你希望能够对所有出现的集合执行(有序)设置操作,尤其是对先前设置操作的结果也

  • 问题内容: 基本上,我的问题与这一问题相同,但是对于Java的(JBoss)Hibernate:我们如何使用hibernate标准API将列作为int排序?我想创建一个从字符串列转换为int的订单限制。就像是 唯一的例外是“无法解析属性:[Class]的演员表(id为int)”。我已经尝试过使用int和integer进行cast(as)和convert(,)。 问题答案: 尽管主题很旧,可能是问题