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

bil*_*lak 3 java java-8 completable-future

我有以下要求.

  1. CreateDocument
  2. 对于文档创建许多发行说明(releaseNotesFuture)
  3. 对于文档创建许多宗地(parcelsFuture)
  4. 返回1中创建的文档的objectId.

这是我目前的代码:

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;
    }
Run Code Online (Sandbox Code Playgroud)

我怎么能等待releaseNotesFutureparcelsFuture完成然后返回deliveryNoteFuture结果或错误,如果有任何releaseNotesFutureparcelsFuture完成异常?

Sot*_*lis 5

而不是返回的deliveryNoteFuture,你必须有一个CompletableFuture被完成时releaseNotesFutureparcelsFuture完成.此外,你会希望未来然后构成结果deliveryNoteFuture,因为你想要它,ObjectId如果整个链是成功的.

就像是

return CompletableFuture.allOf(releaseNotesFuture, parcelsFuture).thenComposeAsync(r -> deliveryNoteFuture);
Run Code Online (Sandbox Code Playgroud)

由于这两个releaseNotesFutureparcelsFuture依赖deliveryNoteFuture,从错误deliveryNoteFuture将通过所有这些链传播.

类似地,如果其中一个releaseNotesFutureparcelsFuture失败,CompletableFuture返回的allOf将由该失败的原因完成,并且该原因将传播到返回的将来thenComposeAsync.否则,结果deliveryNoteFuture将被传递.


正如霍尔格所说,既然你只有这两个期货,你也可以使用thenCombine

releaseNotesFuture.thenCombineAsync(parcelsFuture, (x, y) -> deliveryNoteFuture.join());
Run Code Online (Sandbox Code Playgroud)

join()由于deliveryNoteFuture肯定已经完成,因此不会阻止.同样,如果deliveryNoteFuture最初失败了,它的原因将沿着以CompletableFuture返回的结尾的链传播thenCombineAsync.

  • 或者`releaseNotesFuture.thenCombine(parcelsFuture,(x,y) - > deliveryNoteFuture.join());` (4认同)