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

CompletableFuture get result of first future waiting for other futures depending of first one

我有以下要求。

  1. 创建文档
  2. 为文档创建许多发行说明 (releaseNotesFuture)
  3. 为文档创建多个包裹 (parcelsFuture)
  4. return 在 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;
    }

我如何等待 releaseNotesFutureparcelsFuture 完成,然后 return deliveryNoteFuture 结果或错误,如果 releaseNotesFutureparcelsFuture 异常完成?

而不是返回 deliveryNoteFuture,您必须有一个 CompletableFuture,它在 releaseNotesFutureparcelsFuture 完成时完成。此外,你会希望那个未来组成 deliveryNoteFuture 的结果,因为如果整个链成功,你想要它的 ObjectId

类似

return CompletableFuture.allOf(releaseNotesFuture, parcelsFuture).thenComposeAsync(r -> deliveryNoteFuture);

由于 releaseNotesFutureparcelsFuture 都依赖于 deliveryNoteFuture,来自 deliveryNoteFuture 的错误将通过所有这些链传播。

类似地,如果 releaseNotesFutureparcelsFuture 中的任何一个失败,CompletableFuture returned by allOf 将以该失败的原因完成,并且该原因将传播到 [=26 返回的未来=].否则,deliveryNoteFuture的结果将被传递。


作为, since you only have those two futures, you could also use thenCombine

releaseNotesFuture.thenCombineAsync(parcelsFuture, (x, y) -> deliveryNoteFuture.join());

在这里,join() 不会阻塞,因为 deliveryNoteFuture 肯定已经完成了。同样,如果 deliveryNoteFuture 最初失败,其原因将沿着链传播,以 thenCombineAsync 返回的 CompletableFuture 结束。