Die Idee der Verwendung CompletableFuture
ist, weil es eine Kette bietet, während die ersten paar Schritte Bohnen einkapseln, bevor der letzte Schritt es verwendet. Da in diesen Schritten jede Ausnahme auftreten kann, wird exceptionally
verwendet, um Fehler zu behandeln. Allerdings akzeptiert exceptionally
nur Throwable
Argument und bis jetzt habe ich keinen Weg gefunden, diese eingekapselten Bohnen zu greifen.ComplectableFuture bricht die Arbeitskette ausnahmsweise
CompletableFuture.supplyAsync(this::msgSource)
.thenApply(this::sendMsg).exceptionally(this::errorHandler).thenAccept(this::saveResult)
public List<Msg> msgSource() // take message from somewhere.
public List<Msg> sendMsg(List<Msg>) // exceptions may happen like 403 or timeout
public List<Msg> errorHandler() // set a success flag to false in Msg.
public void saveResult(List<Msg>) // save send result like success or false in data center.
Im obigen Beispiel sind Kommentare der Arbeitsablauf. Da jedoch errorHandler
weder List<Msg>
akzeptiert noch weitergibt, ist die Kette also kaputt. Wie bekomme ich die Rückkehr von msgSource
?
EDIT
public class CompletableFutureTest {
private static Logger log = LoggerFactory.getLogger(CompletableFutureTest.class);
public static void main(String[] args) {
CompletableFutureTest test = new CompletableFutureTest();
CompletableFuture future = new CompletableFuture();
future.supplyAsync(test::msgSource)
.thenApply(test::sendMsg).exceptionally(throwable -> {
List<String> list = (List<String>) future.join(); // never complete
return list;
}).thenAccept(test::saveResult);
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private List<String> saveResult(List<String> list) {
return list;
}
private List<String> sendMsg(List<String> list) {
throw new RuntimeException();
}
public List<String> msgSource() {
List<String> result = new ArrayList<>();
result.add("1");
result.add("2");
return result;
}
}
würde das nicht 'success = false 'für alle' Msg' setzen, wenn eine einzige fehlgeschlagen ist? – Eugene
@Eugene: sicher. Wenn 'sendMsg (List)' fehlschlägt, bedeutet dies einen Fehler für die gesamte Liste. So wird der Code der Frage entworfen, der für die Verwendung von 'CompletableFuture' gilt, sowie für die Methoden, die eine' List' empfangen und zurückgeben. –
Holger
Wenn "ausnahmsweise" alle Manipulationen vergißt, die seine früheren Arbeiten an Nachrichten verübten, wäre seine Rückkehr sehr nutzlos. Aber Ihr erstes Codesegment zeigt, dass es eine Möglichkeit gibt, die frühere Arbeit tatsächlich zu entfernen, nur unter der Voraussetzung, dass man vorausahnt, welche Arbeit die Ausnahme verursacht *. Was ich dachte, war das Argument (in diesem Fall die 'Liste') der Funktion, die die Ausnahme in 'ausnahmsweise' auslöst. Manchmal könnte diese Kette länger sein und versuchen, in jedem von ihnen einzufangen, könnte meistens bedeutungslos sein. –
Tiina