How do I wait in a flattenMap block for a signal to complete before the next event is consumed?

风格不统一 提交于 2019-12-13 08:08:14

问题


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


回答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?



来源:https://stackoverflow.com/questions/22298551/how-do-i-wait-in-a-flattenmap-block-for-a-signal-to-complete-before-the-next-eve

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!