CompletableFuture取决于第一个未来等待其他期货的结果

时间:2017-06-22 16:01:38

标签: java java-8 completable-future

我有以下要求。

  1. CreateDocument
  2. 对于文档创建许多发行说明(releaseNotesFuture)
  3. 对于文档创建许多宗地(parcelsFuture)
  4. 返回在1中创建的文档的objectId。
  5. 这是我目前的代码:

    public CompletableFuture<ObjectId> createDeliveryNoteDocument(String productId, List<String> releaseNotesIds) {
            CompletableFuture<ObjectId> deliveryNoteFuture =
                    CompletableFuture
                            .supplyAsync(() -> sequenceServiceFeignClient.getNextValueForSequenceNameNoResponseEntity(DocumentType.DELIVERYNOTE.toString()))
                            .whenComplete((result, error) -> {
                                if (error != null)
                                    logger.error("Unable to get next sequence number for DELIVERYNOTE sequence", error);
                            })
                            .thenCompose(seqNumber -> {
                                Set<ObjectAttribute> objectAttributes = new HashSet<>();
                                objectAttributes.add(new ObjectAttribute(Constants.Document.DOCUMENT_TYPE, DocumentType.DELIVERYNOTE.toString()));
                                objectAttributes.add(new ObjectAttribute(Constants.Document.DOCUMENT_NO, seqNumber));
                                objectAttributes.add(new ObjectAttribute(Constants.Document.PRODUCT_ID, productId));
                                return objectCommandService.createCustomObject(new ObjectTypeTableName(Constants.ObjectTables.DOCUMENT), objectAttributes);
                            });
            CompletableFuture<Void> releaseNotesFuture =
                    deliveryNoteFuture
                            .thenComposeAsync(deliveryNoteId -> joinReleaseNotesWithDeliveryNote(deliveryNoteId, releaseNotesIds));
    
            CompletableFuture<Void> parcelsFuture =
                    deliveryNoteFuture
                            .thenComposeAsync(deliveryNoteId -> changeParcelsStatusForReleaseNotes(releaseNotesIds));
    
            return deliveryNoteFuture;
        }
    

    我如何等待releaseNotesFutureparcelsFuture完成,然后如果deliveryNoteFuturereleaseNotesFuture中的任何一个异常完成,则返回parcelsFuture结果或错误?

1 个答案:

答案 0 :(得分:5)

deliveryNoteFutureCompletableFuture完成后,您必须完成releaseNotesFuture,而不是返回parcelsFuture。此外,您希望将来会构成deliveryNoteFuture的结果,因为如果整个链条成功,您需要ObjectId

这样的东西
return CompletableFuture.allOf(releaseNotesFuture, parcelsFuture).thenComposeAsync(r -> deliveryNoteFuture);

由于releaseNotesFutureparcelsFuture都依赖于deliveryNoteFuture,因此来自deliveryNoteFuture的错误将传播到所有这些链中。

同样,如果releaseNotesFutureparcelsFuture中的任何一个失败,CompletableFuture returned by allOf将完成该失败的原因,并且该原因将传播到{返回的未来{ {1}}。否则,thenComposeAsync的结果将被传递。

作为Holger suggests,由于您只有这两个期货,您还可以使用thenCombine

deliveryNoteFuture

此处,自releaseNotesFuture.thenCombineAsync(parcelsFuture, (x, y) -> deliveryNoteFuture.join()); 以来join()赢得的阻止肯定已经完成。同样,如果deliveryNoteFuture最初失败,其原因将沿着以deliveryNoteFuture返回的CompletableFuture结尾的链传播。