2017-02-21 3 views
1

Ich bin neu in Java und bin mit CompletableFutures Asynchron-Operationen wie unten auszuführen:Java - Pause Ausführungssequenz mit CompletableFuture Kette

public CompletionStage<Either<ErrorResponse, Response>> insertOrUpdate(String actor, String key) { 
    return this.objectDAO.getByKey(key) 
      .thenApply(mapDOToContainer(key)) 
      .thenApply(mergeContainerToDO(key, actor)) 
      .thenComposeAsync(this.objectDAO.UpdateFn()) 
      .thenApply(DBResult::finished) 
      .thenApply(finished -> { 
       if (finished) { 
        Response response = Response.ok().build(); 
        return Either.right(response); 
       } else { 
        return Either.left(ErrorResponse.create("Error", 400)); 
       } 
      }); 
} 

Jetzt muß ich dies ändern, so dass, wenn die get versagt, dann führe ich die obige Kette, aber wenn es erfolgreich ist, dann muss ich diese Kette brechen und von der Funktion mit einem Entweder-Objekt zurückkommen, das eine ErrorResponse enthält.

Wie kann ich diese Verarbeitungskette unterbrechen? Ich weiß, dass ich eine Markierung an jede Funktion in der Kette übergeben kann und erreiche dies, indem ich die Aktionen in den Funktionen basierend auf dem Wert des Flags ausführe. Ich hatte gehofft, dass es einen besseren Weg dafür gibt.

Danke !!

+0

Eine Ausnahme unterbricht die Kette. CompletableFutures haben spezielle Methoden, um mit dem Ausnahmefall umzugehen. Ich würde "Entweder" überhaupt nicht verwenden, um Fehler zurückzugeben, es ist für Sprachen, die keine Ausnahmen haben. – john16384

+0

Sie könnten eine [Optional] (https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html) wie 'Optional.of (objectDAO.getByKey (key))' anwenden. Oder die Methode des DAO könnte optional zurückgeben, weil es offensichtlich eine Option gibt, dass dieses DAO den Schlüssel nicht findet. Der Punkt ist: [ifPresent] (https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ifPresent-java.util.function.Consumer-) ist hier praktisch. –

Antwort

0

Ich würde Ihren Code neu schreiben.

  • Verwenden Sie entweder für Fehler nicht, Ausnahme Java hat
  • Sie einen CompletionStag von Ihrem DAO
  • Verwenden exceptionally von CompletableFuture nicht zurück, es für diesen

Dann tun konzipiert dies:

public CompletionStage<Response> insertOrUpdate(String actor, String key) { 
    return CompletableFuture.supplyAsync(() -> this.objectDAO.getByKey(key)) 
      .thenApply(mapDOToContainer(key)) 
      .thenApply(mergeContainerToDO(key, actor)) 
      .thenComposeAsync(this.objectDAO.UpdateFn()) 
      .thenApply(DBResult::finished) 
      .thenApply(finished -> { 
       Response response = Response.ok().build(); 
       return response; 
      }) 
      .exceptionally(e -> ErrorResponse.create("Error", 400)); 
} 

Die DAO sollte wie folgt sein:

Möglicherweise müssen Sie sicherstellen, dass ErrorResponse eine Unterklasse von Response ist, damit dies funktioniert.

+0

Danke! Ich war ein wenig verwirrt über die Verwendung von außergewöhnlich, aber das löscht es. – Rohit