将 RACCommand 与异步网络操作一起使用

Posted

技术标签:

【中文标题】将 RACCommand 与异步网络操作一起使用【英文标题】:Use RACCommand with Asynchronous Network Operation 【发布时间】:2013-04-02 17:58:56 【问题描述】:

我正在使用UAGitHubEngine 访问 GitHub 的 API。我想编写一个功能性的反应式应用程序来获取一些数据。我依靠代码here 来设置异步网络请求。我正在寻找的是一些名为“General”的团队的团队 ID。我可以完成过滤/打印部分:

[[self.gitHubSignal filter:^BOOL(NSDictionary *team) 
    NSString *teamName = [team valueForKey:@"name"];
    return [teamName isEqualToString:@"General"];
] subscribeNext:^(NSDictionary *team) 

    NSInteger teamID = [[team valueForKey:@"id"] intValue];

    NSLog(@"Team ID: %lu", teamID);
];

但是设置命令对我来说是个谜:

self.gitHubCommand = [RACCommand command];

self.gitHubSignal = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) 
    RACSignal *signal = ???

    return signal;
];

如何设置信号块以在某些异步网络调用返回时返回一个推送事件的信号?

【问题讨论】:

【参考方案1】:

答案在RACReplaySubject,其中AFNetworking uses 包装了它的异步请求。

self.gitHubCommand = [RACCommand command];

self.gitHubSignals = [self.gitHubCommand addSignalBlock:^RACSignal *(id value) 
    RACReplaySubject *subject = [RACReplaySubject subject];

    [engine teamsInOrganization:kOrganizationName withSuccess:^(id result) 

        for (NSDictionary *team in result)
        
            [subject sendNext:team];
        

        [subject sendCompleted];            
     failure:^(NSError *error) 
        [subject sendError:error];
    ];

    return subject;
];

由于addSignalBlock: 返回一个信号信号,我们需要订阅它发出的下一个信号。

[self.gitHubSignals subscribeNext:^(id signal) 
    [signal subscribeNext:^(NSDictionary *team) 
        NSInteger teamID = [[team valueForKey:@"id"] intValue];

        NSLog(@"Team ID: %lu", teamID);
    ];
];

最后,addSignalBlock: 块在命令执行之前不会执行,我通过以下方式进行管理:

[self.gitHubCommand execute:[NSNull null]];

【讨论】:

以上是关于将 RACCommand 与异步网络操作一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Array.prototype.filter 与异步一起使用?

将 HttpContext.Current.User 与异步等待一起使用的正确方法

iOS-RAC常用方法

将 fetch api 与 ramda 一起使用

Nock 不能与 axios 一起使用获取操作异步测试

FlutterFutureBuilder 异步编程 ( FutureBuilder 构造方法 | AsyncSnapshot 异步计算 )