在 Java 8 中使用来自先前链接的 thenCompose lambdas 的值

我的同事喜欢的 Java 8 编码风格是一直链接异步调用,例如


CompletionStage<E> someMethod() {

    return doSomething().thenCompose(a -> {

      // ...

      return b;

    }).thenCompose(b -> {

      // ...

      return c;

    }).thenCompose(c -> {

      // ...

      return d;

    }).thenApply(d -> {

      // ...

      return e;

    });

}

我有类似上面的东西,但有一个额外的挑战:我需要回忆在一些 lambda 中检索到的值,在以后的 lambda 中。例如,


CompletionStage<E> someMethod() {

    return doSomething().thenCompose(a -> {

      // ...

      Foo foo = fooDAO.getFoos(a);

      // ...

      return b;

    }).thenCompose(b -> {

      // ...

      return c;

    }).thenCompose(c -> {

      // ...

      Bar bar = barDAO.getBars(foo);

      // ...

      return d;

    }).thenApply(d -> {

      // ...

      return someResult(d, bar);

    });

}

当我声明Foo foo;并且Bar bar;在外部范围内时,我会收到关于它们不是最终的或实际上是最终的错误。我读到使用包装器使它们有效地成为最终版本,但对我来说这样做似乎很麻烦(我不明白为什么允许这样做......)


我读到 Java 8 没有添加对元组的支持(尽管它考虑过BiVal,也许我可以用来传递给BiFunctionlambdas)。所以我尝试使用对,例如


    return doSomething().thenCompose(a -> {

      // ...

      Foo foo = fooDAO.getFoos(a);

      // ...

      return new Pair<>(foo, b);

    }).thenCompose(fooAndB -> {

然后我需要回忆的地方foo,


      Foo foo = fooAndB.getKey();

但这感觉在语义上是错误的。此外,它不起作用!我不知道为什么,因为我认为 lambda 参数的范围与其外部范围相同,因此所有 lambda 参数都可以从后续链接的 lambda 中访问。


lambda 参数的真正范围是什么,是否有一种惯用的或至少在语义上没有攻击性的方式来做我想做的事情,同时保持链接?


基于打破链条的答案很好,因为它们可能对未来的观众有用,但在我的情况下,与此 repo 中的主导风格的偏差可能导致公关对话和延迟批准,所以我喜欢一个解决方案,保留链接。或者,解释或演示尝试保持链接是多么疯狂。谢谢!


蝴蝶不菲
浏览 218回答 3
3回答

汪汪一只猫

您可以尝试这种方法(我不一定提倡这样做,但它确实维护了链条)。您创建一个包含链所需的所有参数的 POJO,并将相同的 POJO 向下传递。这里的缺点是向链中添加其他方法有点麻烦,因为您现在还必须向参数类添加一个属性。public class SomeMethodContext {&nbsp; &nbsp; private Object a;&nbsp; &nbsp; private Object b;&nbsp; &nbsp; private Object c;&nbsp; &nbsp; private Object d;&nbsp; &nbsp; private Object foo;&nbsp; &nbsp; private Object bar;&nbsp; &nbsp; // Getters and setters}// ...CompletionStage<E> someMethod() {&nbsp; &nbsp; return doSomething().thenCompose(a -> {&nbsp; &nbsp; &nbsp; SomeMethodContext context = new SomeMethodContext();&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; context.setA(a);&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; context.setFoo(fooDAO.getFoos(context.getA()));&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; context.setB(b);&nbsp; &nbsp; &nbsp; return context;&nbsp; &nbsp; }).thenCompose(ctxt -> {&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; ctxt.setC(c);&nbsp; &nbsp; &nbsp; return ctxt;&nbsp; &nbsp; }).thenCompose(ctxt -> {&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; ctxt.setBar(barDAO.getBars(ctxt.getFoo()))&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; ctxt.setD(d)&nbsp; &nbsp; &nbsp; return ctxt;&nbsp; &nbsp; }).thenApply(ctxt -> {&nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; return someResult(ctxt.getD(), ctxt.getBar());&nbsp; &nbsp; });}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java