3

Supposons que j'ai 3 téléchargements, libellé comme des contrats à terme pouvant être complétée:CompletableFuture: Comment appliquer une fonction à plusieurs CompletableFutures?

CompletableFuture<Doc> dl1 = CompletableFuture.supplyAsync(() -> download("file1")); 
    CompletableFuture<Doc> dl2 = CompletableFuture.supplyAsync(() -> download("file2")); 
    CompletableFuture<Doc> dl3 = CompletableFuture.supplyAsync(() -> download("file3")); 

Puis tous d'entre eux doivent être traités de la même manière

CompletableFuture<String> s1 = dl1.thenApply(Doc::getFilename); 
    CompletableFuture<String> s2 = dl2.thenApply(Doc::getFilename); 
    CompletableFuture<String> s3 = dl3.thenApply(Doc::getFilename); 

Et vous pouvez imaginer de multiples fonctions à appliquer, tout en parallèle. Selon le principe DRY, cet exemple semble inapproprié. Donc je cherche une solution pour définir seulement 1 workflow qui est exécuté 3 fois, en parallèle.

Comment cela peut-il être accompli?

J'ai essayé allOf, mais cela a deux problèmes 1) il commence à bloquer et 2) le type de retour peut seulement run choses au lieu de le gérer.

+4

déclarer une nouvelle méthode qui appelle d'abord à télécharger, puis à getFilename –

+1

avez-vous pensé à mettre les fichiers dans une liste, puis itérer sur eux? – Ash

Répondre

5
Stream.of("file1", "file2", "file3") // or your input in any other format, that can easily be transformed to a stream... 
     // .parallel() // well... depends... 
     .map(s -> CompletableFuture.supplyAsync(() -> download(s))) 
     .map(dl -> dl.thenApply(Doc::getFilename)) 
     .map(CompletableFuture::join) // if you want to have all the results collected 
     .collect(Collectors.toList()); 

Bien sûr aussi les deux map peuvent être combinés: permet d'appeler. Mais au moins vous n'écrivez pas tout x fois ... Si vous n'aimez pas la collection à List, vous pouvez également appeler autre chose dessus, par ex. .forEach(System.out::println). Le .forEach a l'avantage, que dès que la réponse est disponible, le consommateur est appelé.

Ou le classique: il suffit d'utiliser une boucle et une liste/tableau pour votre entrée, mais vous devrez peut-être prendre en charge plus que vous auriez avec flux