在ReactiveCocoa中链接相关的信号
在ReactiveCocoa中,如果我们链接几个依赖信号,我们必须使用subscribeNext:
链中的下一个信号来接收生成的前一个信号的值(例如asynchronous操作的结果)。 所以一段时间后,代码变成这样的东西(不必要的细节被省略):
RACSignal *buttonClickSignal = [self.logIn rac_signalForControlEvents:UIControlEventTouchUpInside]; [buttonClickSignal subscribeNext:^(UIButton *sender) { // signal from a button click // prepare data RACSignal *loginSignal = [self logInWithUsername:username password:password]; // signal from the async network operation [loginSignal subscribeNext:^void (NSDictionary *json) { // do stuff with data received from the first network interaction, prepare some new data RACSignal *playlistFetchSignal = [self fetchPlaylistForToken:token]; // another signal from the async network operation [playlistFetchSignal subscribeNext:^(NSDictionary *json) { // do more stuff with the returned data }]; // etc }]; }];
这个不断增加的嵌套看起来不如文档中给出的非react native示例好得多:
[client logInWithSuccess:^{ [client loadCachedMessagesWithSuccess:^(NSArray *messages) { [client fetchMessagesAfterMessage:messages.lastObject success:^(NSArray *nextMessages) { NSLog(@"Fetched all messages."); } failure:^(NSError *error) { [self presentError:error]; }]; } failure:^(NSError *error) { [self presentError:error]; }]; } failure:^(NSError *error) { [self presentError:error]; }];
我错过了什么吗? 在ReactiveCocoa中有更好的链式依赖工作模式吗?
这是RACStream和RACSignal运营商开始真正派上用场的时候。 在您的具体示例中,您可以使用-flattenMap:
将结果合并到新信号中:
[[[buttonClickSignal flattenMap:^(UIButton *sender) { // prepare 'username' and 'password' return [self logInWithUsername:username password:password]; }] flattenMap:^(NSDictionary *json) { // prepare 'token' return [self fetchPlaylistForToken:token]; }] subscribeNext:^(NSDictionary *json) { // do stuff with the returned playlist data }];
如果您不需要任何步骤的结果,您可以使用-sequenceMany:
或-sequenceNext:
来代替类似的效果(但是为了更清楚地expression意图)。