我最初编写这段代码是因为这是我的看法,但是我想研究如何删除递归。
这个想法是我有一个要渲染的指令列表。渲染器仅凭一条指令就给了我一个可以完成的未来。结果有时可能无效,因此我想在下一条指令上调用渲染器。我想返回呈现有效结果的第一条指令。
我想请一个学习的人看一下,并在可能的情况下给我一些想法。
/**
* I want a a completable future for a list of instructions, returning
* me the first valid result for the instruction input.
*/
private CompletableFuture<Result> getFutureResult(final List<Instruction> instructions) {
final CompletableFuture<Result> futureResult = new CompletableFuture<>();
renderAux(futureResult, instructions.iterator());
return futureResult;
}
/**
* This is actually an external method that will return a completable
* future for only one instruction. I cannot modify this API.
*/
private CompletableFuture<Result> render(final Instruction instruction) {
/.../
}
/**
* This method is called recursively for the current instruction in the
* the iterator, if the result if not valid, we call on the next instruction.
*/
private void renderAux(
final CompletableFuture<Result> futureResult,
final Iterator<Instruction> instructionIterator) {
final Instruction instruction = instructionIterator.next();
final boolean isLast = !instructionIterator.hasNext();
render(instruction).whenComplete((result, e) -> {
if (result.isValid() || isLast) {
// Complete the future on the first valid result, or
// if this is the last instruction.
futureResult.complete(result);
} else {
// Recursive call for the next instruction.
renderAux(futureResult, instructionIterator);
}
});
}
最佳答案
您可以直接使用CompletableFuture.handle()
方法将期货链接在一起:
private CompletableFuture<Result> getFutureResult(final List<Instruction> instructions) {
CompletableFuture<Result> futureResult = null;
for (Instruction instruction : instructions) {
if (futureResult == null) {
futureResult = render(instruction);
} else {
futureResult = futureResult.handle((result, e) -> {
if (result.isValid())
return result;
else
return render(instruction).join();
});
}
}
return futureResult;
}
这会为您列表中的每条指令创造一个新的未来,但执行的指令数量仍然没有必要。