Combine framework: how to process each element of array asynchronously before proceeding

后端 未结 2 1651
一整个雨季
一整个雨季 2021-01-04 09:46

I\'m having a bit of a mental block using the iOS Combine framework.

I\'m converting some code from \"manual\" fetching from a remote API to using Combine. Basically

2条回答
  •  情话喂你
    2021-01-04 10:47

    With your latest edit and this comment below:

    I literally am asking is there a Combine equivalent of "don't proceed to the next step until this step, involving multiple asynchronous steps, has finished"

    I think this pattern can be achieved with .flatMap to an array publisher (Publishers.Sequence), which emits one-by-one and completes, followed by whatever per-element async processing is needed, and finalized with a .collect, which waits for all elements to complete before proceeding

    So, in code, assuming we have these functions:

    func getFoos() -> AnyPublisher<[Foo], Error>
    func getPartials(for: Foo) -> AnyPublisher<[Partial], Error>
    func getMoreInfo(for: Partial, of: Foo) -> AnyPublisher
    

    We can do the following:

    getFoos()
    .flatMap { fooArr in 
        fooArr.publisher.setFailureType(to: Error.self)
     }
    
    // per-foo element async processing
    .flatMap { foo in
    
      getPartials(for: foo)
        .flatMap { partialArr in
           partialArr.publisher.setFailureType(to: Error.self)
         }
    
         // per-partial of foo async processing
        .flatMap { partial in
    
           getMoreInfo(for: partial, of: foo)
             // build completed partial with more info
             .map { moreInfo in
                var newPartial = partial
                newPartial.moreInfo = moreInfo
                return newPartial
             }
         }
         .collect()
         // build completed foo with all partials
         .map { partialArr in
            var newFoo = foo
            newFoo.partials = partialArr
            return newFoo
         }
    }
    .collect()
    

    (Deleted the old answer)

提交回复
热议问题