如何在Java8中多次使用thenCompose的结果?

如何在Java8中多次使用thenCompose的结果?,java,java-8,future,completable-future,Java,Java 8,Future,Completable Future,我有一系列然后撰写调用,类似于 myObject.updateDB(payload) .thenCompose(__ -> getUserID(payload.ID())) .thenCompose(id -> getProfile(id)) .thenCompose(userProfile -> updateSomething(userProfile)) .thenCompose(__ -> notifyUser(id))

我有一系列
然后撰写
调用,类似于

myObject.updateDB(payload)
      .thenCompose(__ -> getUserID(payload.ID()))
      .thenCompose(id -> getProfile(id))
      .thenCompose(userProfile -> updateSomething(userProfile))
      .thenCompose(__ -> notifyUser(id))
      .thenAccept(__ -> doSomething())
      .exceptionally(t -> doSomethingElse());
getUserID
调用返回一个
CompletionStage
,我在下一次调用
getProfile
时使用它。对于
notifyUser
调用,我需要同样的
id
。如何在那里提供?IDE正在显示

无法解析符号id


当前代码的问题是,当您到达
。然后单击compose(\uu->notifyUser(id))
时,变量
id
不再在范围内

在这种情况下,一个简单的解决方案是在
getProfile
返回的
CompletionStage
上直接调用多个
,然后合成:

myObject.updateDB(payload)
  .thenCompose(__ -> getUserID(payload.ID()))
  .thenCompose(id -> 
      getProfile(id)
          .thenCompose(userProfile -> updateSomething(userProfile))
          .thenCompose(__ -> notifyUser(id))
  )
  // rest of chain calls

我认为,如果您不坚持在每个步骤中使用
然后编写
,代码就会变得更简单:

myObject.updateDB(payload)
    .thenCompose(__ -> getUserID(payload.ID()))
    .thenAccept(id -> {
        updateSomething(getProfile(id).join());
        notifyUser(id);
    })
    .thenRun(() -> doSomething())
    .exceptionally(t -> doSomethingElse());
如果要求每个步骤有效地按顺序进行,您只需使用
join

myObject.updateDB(payload)
    .thenCompose(__ -> getUserID(payload.ID()))
    .thenAccept(id -> {
        updateSomething(getProfile(id).join()).join();
        notifyUser(id).join();
    })
    .thenRun(() -> doSomething())
    .exceptionally(t -> doSomethingElse());
考虑到整个链实际上是连续的,您可以直接写出来:

myObject.updateDB(payload)
    .thenRun(() -> {
        YourUserIDType id = getUserID(payload.ID()).join();
        updateSomething(getProfile(id).join()).join();
        notifyUser(id).join();
        doSomething();
    })
    .exceptionally(t -> doSomethingElse());

这不是一个简单的解决方案。一个简单的解决方案是将
compose
d链转换为单个代码块。在如此多的阶段中表达这种完全线性的序列是没有好处的。通过将其作为单个操作写入,所有需要的值都在范围内,并且所有这些未使用的参数都将消失…