Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objc PromiseKit: Add new promises from within a promise

I'm using PromiseKit to simply my API requests.

In this scenario, I'm fetching a list of objects IDs from the server. I need to then fetch details for each ID, and return an array of details. Fairly common scenario.

Effectively, I need to add promises to the promise chain from within a FOR loop which is contained in the FIRST promise.

I've created code that begins to drift right, but the chain completes before the second chain of promises (fill shallow model requests) can be executed.

[PMKPromise promiseWithResolver:^(PMKResolver resolve) {
    // Fetch an array of object IDs (shallow objects)
    [APIManager fetchObjectListWithCompletion:^(NSArray *resultObjects, NSError *error) {
        resolve(error ?: resultObjects[0]);
    }];
}].then(^(NSArray *objects){
    // Fill each shallow object (query details)
    PMKPromise *fetches = [PMKPromise promiseWithValue:nil];
    for(id model in objects) {
      fetches.then(^{
            [APIManager fillShallowObject:model withCompletion:^(NSArray *resultObjects, NSError *error) {
              // resolve?
            }];
        });
    }

    // Return promise that contains all fill requests
    return fetches; 
})].then(^{
    // This should be executed after all fill requests complete
    // Instead it's executed after the initial ID array request
});

Is there a better way to do what I'm trying to accomplish? Perhaps a way to append a promise (.then) with a resolver?

like image 876
chris stamper Avatar asked Oct 30 '22 23:10

chris stamper


1 Answers

I think you want when:

[AnyPromise promiseWithAdapterBlock:^(id adapter) {
    [APIManager fetchObjectListWithCompletion:adapter];
}].then(^(id objects){
    NSMutableArray *promises = [NSMutableArray new];
    for (id model in objects) {
        id promise = [AnyPromise promiseWithAdapterBlock:^(id adapter){
            [APIManager fillShallowObject:model withCompletion:adapter];
        }];
        [promises addObject:promise];
    }
    return PMKWhen(promises);
}).then(^(NSArray *results){
    // when waits on all promises
});

Code is PromiseKit 3.

like image 51
mxcl Avatar answered Nov 15 '22 10:11

mxcl