我有以下要求。

  • CreateDocument
  • 为文档创建许多发行说明(releaseNotesFuture)
  • 为文档创建许多宗地(parcelsFuture)
  • 返回在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中的任何一个异常完成,我该如何等待deliveryNoteFuturereleaseNotesFuture完成,然后返回parcelsFuture结果或错误?

    最佳答案

    除了返回deliveryNoteFuture之外,您还必须具有在CompletableFuturereleaseNotesFuture完成时完成的parcelsFuture。此外,您希望将来可以将其合并到deliveryNoteFuture的结果中,因为如果整个链都成功,您希望其ObjectId

    就像是

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

    由于releaseNotesFutureparcelsFuture都取决于deliveryNoteFuture,因此deliveryNoteFuture的错误将通过所有这些链传播。

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

    Holger suggests一样,由于您只有这两种期货,因此您也可以使用 thenCombine
    releaseNotesFuture.thenCombineAsync(parcelsFuture, (x, y) -> deliveryNoteFuture.join());
    

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

  • 09-11 18:36