0

here is my pseudo code :

[[[@[ctx1,ctx2]rac_sequence]signalWithScheduler:RACScheduler.immediateScheduler]

flattenMap:^RACStream *(id ctx) 
{
    // first flatten map
    return [RACSignal createSignal:^(id <RACSubscriber> subscriber) 
    {
        [executeRequestAsynch 
             onDone:^{
             [subscriber sendNext:ctx];  
             [subscriber sendCompleted]; 
    }
    ]

    }]
    flattenMap:^RACStream *(id ctx) {

    // second flattenMap  
    }];

}

Now here is what I want to happen upon subscribe:

1)  ctx1 should get fed to the first flattenMap block
2)  the Server Request "executeRequestAsynch" should be called
3)  on completion of the serverRequest the second flattenMap should be called with ctx1
4)  ctx2 should get fed to the first flattenMap block
5)  the Server Request "executeRequestAsynch" should be called
6)  on completion of the serverRequest the second flattenMap should be called with ctx1

But instead this scenario happens:

1)  ctx1 gets fed to the first flattenMap block
2)  the Server Request "executeRequestAsynch" is called
3)  ctx2 gets fed to the first flattenMap block
4)  the Server Request "executeRequestAsynch" is called
5)   on completion of the serverRequest the second flattenMap is called with ctx1
6)  on completion of the serverRequest the second flattenMap is called with ctx2

How can I make the first scenario happen?


answer this seems to do the work! thanks: output is:

 Step 1
   Step 1 child
     Step 1    child child
 Step 2
   Step 2 child
     Step 2    child child
 done all

I am still wondering what defer will achieve in the underneath senario

-(RACSignal*) executeRequestAsynch:(NSString*) ctx {
 return [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {
     NSLog(@"  %@ child",ctx);
     [subscriber sendCompleted];
                 return nil;
        }];

}

-(RACSignal*) executeRequestAsynch2:(NSString*) ctx {
return [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {
    NSLog(@"  %@    child child",ctx);
    [subscriber sendCompleted];
    return nil;
}];

 }

  - (void)viewDidLoad
{
    [super viewDidLoad];
    RACSignal *contexts = [[@[ @"Step 1", @"Step 2" ] 
    rac_sequence]  signalWithScheduler:RACScheduler.immediateScheduler];
    RACSignal *ne = [[contexts map:^(id ctx) {
    NSLog(@"%@",ctx);
    return [[self executeRequestAsynch:ctx] concat: [self executeRequestAsynch2:ctx ]];}]concat] ;
   [ne subscribeCompleted:^{
    NSLog(@"done all");
}];
}

here is my final real solution

Community
  • 1
  • 1
jack
  • 1,861
  • 4
  • 31
  • 52

1 Answers1

1

I'm not 100% sure I understand what you're trying to accomplish. My interpretation is something like:

RACSignal *contexts = [@[ ctx1, ctx2 ] things.rac_sequence signalWithScheduler:RACScheduler.immediateScheduler];
[[contexts map:^(id ctx) {
    return [executeRequestAsynch concat:[RACSignal defer:^{
        // Returns another signal involving ctx?
    }]];
}] concat];

This maps each of the context to a executeRequestAsynch, and then concats them so that they are done serially.

Is that right or did I misunderstand you?

joshaber
  • 2,465
  • 20
  • 13
  • maybe you did misunderstand me. sorry for being not clear enough. I want the whole block of flattenMap to execute with ctx1 and on completion then I want the flattenMap to execute with ctx2. right now if i would put NSLog("ctx name %@",ctx) in the flattenMap I would see "ctx name 1" and then "ctx name 2" and then the logging from executeRequestAsynch. But I want: "ctx name 1" then logging from executeRequestAsynch and only then "ctx name 2"... But give me an hour and I see what I can achieve with defer – jack Mar 10 '14 at 15:20
  • well defer does not seem to do what I want. – jack Mar 10 '14 at 16:52
  • I edited my answer to use `-map:` and `-concat` instead of `-flattenMap:`. That might be more what you want. – joshaber Mar 10 '14 at 20:09
  • ok I will try it out. I am having difficulties understanding why I need to user defer instead of concating the signals directly – jack Mar 10 '14 at 21:02
  • somehow the defer signal does not get executed? do I need to do something different than calling completed as the last statement? – jack Mar 10 '14 at 21:27
  • You only need the `+defer:` if you need to defer the signal return until it is subscribed to. – joshaber Mar 12 '14 at 03:43