Retrying an asynchronous operation using ReactiveCocoa

前端 未结 1 1339
失恋的感觉
失恋的感觉 2020-12-31 21:15

I\'m using ReactiveCocoa signals to represent calls to RESTful backend in our system. Each RESTful invocation should receive a token as one of the parameters. The token itse

相关标签:
1条回答
  • 2020-12-31 21:58

    First of all, subscriptions and subjects should generally be avoided as much as possible. Nested subscriptions, in particular, are quite an anti-pattern—usually there are signal operators that can replace them.

    In this case, we need to take advantage of the fact that signals can represent deferred work, and create only one signal to perform the actual request:

    // This was originally the `first` signal.
    RACSignal *apiCall = [RACSignal defer:^{
        return [self apiCall:base params:p get:get];
    }];
    

    The use of +defer: here ensures that no work will begin until subscription. An important corollary is that the work can be repeated by subscribing multiple times.

    For example, if we catch an error, we can try fetching a token, then return the same deferred signal to indicate that it should be attempted again:

    return [[apiCall
        catch:^(NSError *error) {
            // If an error occurs, try requesting a token.
            return [[self
                action:@"logon" email:session.user.email password:session.user.password]
                flattenMap:^(NSDictionary *json) {
                    NSString *token = json[@"token"];
    
                    p[@"token"] = token;
                    session.token = token;
    
                    // Now that we have a token, try the original API call again.
                    return apiCall;
                }];
        }]
        replay];
    

    The use of -replay replaces the RACReplaySubject that was there before, and makes the request start immediately; however, it could also be -replayLazily or even eliminated completely (to redo the call once per subscription).

    That's it! It's important to point out that no explicit subscription was needed just to set up the work that will be performed. Subscription should generally only occur at the "leaves" of the program—where the caller actually requests that work be performed.

    0 讨论(0)
提交回复
热议问题