美文网首页
tryMap和try

tryMap和try

作者: 飞羽田海 | 来源:发表于2021-12-03 14:47 被阅读0次
    • tryMap
      RACSignal的一般用法是:
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"我是发送的数据"];
            [subscriber sendError:[NSError errorWithDomain:@"www.huang"
                                                      code:0
                                                  userInfo:@{NSLocalizedDescriptionKey:@"错误信息"}]];
            return nil;
        }];
        [signal subscribeNext:^(id x) {
            NSLog(@"next:%@",x);
        } error:^(NSError *error) {
            NSLog(@"error:%@",error.localizedDescription);
        }];
      
       ---------
       打印结果:
        next:我是发送的数据
        error:错误信息
      
      如果想对subscriber发送的数据进行一些处理(比如筛选符合预期的数据走next回调,不符合预期的走error回调),应该怎么操作呢?
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"我是发送的数据"];
            return nil;
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"next:%@",x);
        } error:^(NSError *error) {
            NSLog(@"error:%@",error.localizedDescription);
        }];
      
      此时tryMap就能排上用场了
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"我是发送的数据"];
            return nil;
        }];
        
        RACSignal *newSignal = [signal tryMap:^id(id value, NSError *__autoreleasing *errorPtr) {
            if ([value isKindOfClass:[NSNumber class]]) {
                // 符合预期 返回原本的值
                return value;
            } else {
                // 不符合预期,走error回调
                NSError *error = [NSError errorWithDomain:@"www.huang"
                                                     code:0
                                                 userInfo:@{NSLocalizedDescriptionKey:@"数据格式错误"}];
                *errorPtr = error;
                // 这里一定要返回nil,相当于拦截了value的值,就不会走next回调了
                return nil;
            }
        }];
      
        // Note: 其实可以使用 tryMap 原来的value,并返回新的value给 next回调
        
        [newSignal subscribeNext:^(id x) {
            NSLog(@"next:%@",x);
        } error:^(NSError *error) {
            NSLog(@"error:%@",error.localizedDescription);
        }];
      
       ---------
       打印结果:
       error:数据格式错误
      
    • try
      tryMap不同,try需要给定一个布尔值来决定subscriber回调的执行逻辑。
         RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"我是发送的数据"];
            return nil;
        }];
        
        /**
         返回值是一个BOOL
         当返回YES时,subscriber 订阅时走next回调
         当返回NO时,subscriber 订阅时走error回调
         */
        RACSignal *newSignal = [signal try:^BOOL(id value, NSError *__autoreleasing *errorPtr) {
            NSError *error = [NSError errorWithDomain:@"www.huang"
                                                          code:0
                                                      userInfo:@{NSLocalizedDescriptionKey:@"数据格式错误"}];
            *errorPtr = error;
            return NO;
           
            /**
             这样并不能修改原来发送的value的值,因为这是形参!!
             value = @(1234);
             return YES;
             */
            
        }];
        
        [newSignal subscribeNext:^(id x) {
            NSLog(@"next:%@",x);
        } error:^(NSError *error) {
            NSLog(@"error:%@",error.localizedDescription);
        }];
      
       ---------
       打印结果:
       error:数据格式错误
      
    • 源码
      - (RACSignal *)try:(BOOL (^)(id value, NSError **errorPtr))tryBlock {
        NSCParameterAssert(tryBlock != NULL);
      
        return [[self flattenMap:^(id value) {
            NSError *error = nil;
            BOOL passed = tryBlock(value, &error);
                   // 关键点 passed是否为YES
            return (passed ? [RACSignal return:value] : [RACSignal error:error]);
        }] setNameWithFormat:@"[%@] -try:", self.name];
      }
      
      - (RACSignal *)tryMap:(id (^)(id value, NSError **errorPtr))mapBlock {
        NSCParameterAssert(mapBlock != NULL);
      
        return [[self flattenMap:^(id value) {
            NSError *error = nil;
            id mappedValue = mapBlock(value, &error);
                    // 关键点: mappedValue是否为nil
            return (mappedValue == nil ? [RACSignal error:error] : [RACSignal return:mappedValue]);
        }] setNameWithFormat:@"[%@] -tryMap:", self.name];
      }
      

    相关文章

      网友评论

          本文标题:tryMap和try

          本文链接:https://www.haomeiwen.com/subject/vlbpxrtx.html