再次理解flattenMap

之前一篇文章ReactiveCocoa的bind源码理解对flattenMap的理解还是差一些,这里将flattenMap的流程用自然语言描述一遍,加深理解。

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [self httpRequest:@"Post" param:@{@"commandKey":@"hello world!"} completion:^(id response) {
        [subscriber sendNext:@"success!"];
        [subscriber sendCompleted];
    }];
    return nil;
}];

RACSignal *return_signal = [signal flattenMap:^RACStream *(id value) {
    return [RACSignal empty];
}];

上述代码signal称为源信号。

订阅return_signal的流程如下:
1> flattenMap返回一个信号return_signal(由bind创建,参考ReactiveCocoa的bind源码理解);
2> flattenMap的返回信号return_signal被订阅时,执行return_signal的didSubscribe;
3> 执行return_signal的didSubscribe时,会订阅源信号signal,因此源信号的didSubscribe会执行;
4> 当源信号sendNext时,flattenMap的参数block会执行,会得到flattenMap的block执行的返回信号block_return_signal;
5> addSignal(block_return_signal)会继续订阅block_return_signal,订阅block_return_signal的next block仅仅是将值传递出来,不做额外操作。

结论

所以订阅flattenMap的流程是,订阅源信号,获取源信号的sendNext值value,自己新创建一个信号(创建可能依赖value),自动订阅自己创建的信号(如果信号非空),将自己创建的信号的新value直接吐出来。

  1. 所以订阅flattenMap的作用是,利用前一个信号的输出,再创建一个信号(可能使用上个输出)做一些操作,再将操作结果输出。
  2. 所以map的作用是,使用flattenMap,利用前一个信号的输出,再创建一个RACReturnSignal,RACReturnSignal的value就是原信号输出value的转换,再将这个转换值输出。

flattenMap的使用方法

在臧成威的博客中提到接口串联可以使用flattenMap来实现,根据上面的分析和结论可以知道,下一个信号需要等待上一个信号执行完成,传递出value后才能继续。

// 接口串联
    @weakify(self)
    RACSignal *finalSignal = [[self fetchData4]
                              flattenMap:^RACSignal *(NSString *data4Result) {
                                  @strongify(self)
                                  return [self fetchData5:data4Result];
                              }];

你可能感兴趣的:(再次理解flattenMap)