2017-06-22 48 views
2

我有以下要求。CompletableFuture根据第一个未来取得第一个未来等待其他期货的结果

  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; 
        } 
    

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

  • 回答

    4

    而不是返回deliveryNoteFuture,你必须有一个CompletableFuture完成releaseNotesFutureparcelsFuture完成时完成。此外,如果整个链条成功,您将希望这个未来构成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最初失败,则其原因将沿着由thenCombineAsync返回的CompletableFuture结束的链向下传播。

    +4

    或'releaseNotesFuture.thenCombine(parcelsFuture,(x,y) - > deliveryNoteFuture.join());' – Holger

    +1

    谢谢你们......你们俩。最后我使用了Holger的解决方案,因为它非常简单。 – bilak