我是反应性可可的新手。我想要一个信号包含三个信号,所有三个信号都完成然后发送下一个信号。我尝试了concat然后运营商。然后调整用户下一个或完成位置。它总是发送下一个信号然后执行它中的三个信号。我是我的代码。有什么方法可以解决它吗?或者用另一种方式。
- (RACSignal *)replacePubRecentContact {
@weakify(self);
return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
NSMutableArray <RIMRecentContactModel *> *contactModelMutableArray = [NSMutableArray new];
//1 Signal first
RACSignal *selectMessageSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[[[RIMPublicPostDatabaseManager sharedInstance] selectLastMessage] subscribeNext:^(NSArray <RIMRecentContactModel *> *pubContactModelArray) {
//这里穿回来的lastmMessage是一个pmsgId
for (NSUInteger i = 0; i < pubContactModelArray.count; ++i) {
if (pubContactModelArray[i].uid > 0) {
[contactModelMutableArray addObject:pubContactModelArray[i]];
}
}
[subscriber sendNext:@"pub replace select last message bingo"];
[subscriber sendCompleted];
}];
return nil;
}];
//2 Signal second
RACSignal *selectInfoSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
@strongify(self);
for (NSUInteger j = 0; j < contactModelMutableArray.count; ++j) {
@strongify(self);
[[self selectPubInfoWithPid:contactModelMutableArray[j].uid] subscribeNext:^(RIMPubInfoModel *pubInfoModel) {
contactModelMutableArray[j].username = pubInfoModel.name;
contactModelMutableArray[j].avatar = pubInfoModel.logo;
}];
}
[subscriber sendNext:@"pub replace select info bingo"];
[subscriber sendCompleted];
return nil;
}];
//3 Signal third
RACSignal *replaceSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[self.contactDatabaseQueue inDatabase:^(FMDatabase *db) {
for (NSUInteger k = 0; k < contactModelMutableArray.count; ++k) {
RIMRecentContactModel *recentContactModel = contactModelMutableArray[k];
//公众号type 3
recentContactModel.messageType = 3;
NSString *replaceSql = [NSString stringWithFormat:@"REPLACE INTO recentContact (uid, username, avatar, lastMessage, unRead, lastMessageTs, messageType, lastMessageMid, lastMessageSid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"];
//这里因为私聊公众号id重复所以加3
BOOL result = [db executeUpdate:replaceSql, @(recentContactModel.uid), recentContactModel.username, recentContactModel.avatar, recentContactModel.lastMessage, @(recentContactModel.unRead), @(recentContactModel.lastMessageTs), @(recentContactModel.messageType), @(recentContactModel.lastMessageMid), @(recentContactModel.lastMessageSid)];
if (!result) {
NSLog(@"插入最近联系人表失败");
} else {
NSLog(@"插入最近联系人表成功");
}
}
[subscriber sendNext:@"replace公众号最近联系人表成功"];
}];
return nil;
}];
[[[selectMessageSignal concat:selectInfoSignal] then:^RACSignal *{
return replaceSignal;
}] subscribeCompleted:^{
}];
[subscriber sendNext:@"replace pub all bingo"];
[subscriber sendCompleted];
return nil;
}];
}
答案 0 :(得分:0)
您似乎错过了第三个信号中的[subscriber sendCompleted]
,因此永远无法完成。{li>
它可能属于return nil
正上方的循环之外。
您可以使用[RACSignal concat@[selectMessageSignal, selectInfoSignal, replaceSignal]
相互执行这三个信号。
但是,您的selectInfoSignal
无法正常工作,因为它会为contactModelMutableArray
中的每个值启动另一个信号,但不会等待这些信号完成。
您的代码示例实际上比问题建议的要复杂得多。通过在信号外部创建的contactModelMutableArray
数组和信号操作作为副作用,您在这些信号之间具有共享依赖关系,这是您不应该做的,因为那时简单的&#34;如2中所述,将信号连接在一起的解决方案将无法可靠地工作。
在我看来,你实际做的是:
我建议使用以下结构(只是草图)
-(RACSignal *)replacePubRecentContact {
return [[[[self loadRecords] flattenMap:^RACSignal *(NSArray *records) {
return [[records rac_sequence] signal];
}] flattenMap:^RACSignal *(id record) {
return [self infosForRecord:record];
}] flattenMap:^RACSignal * (id record) {
return [self updateRecord:record];
}];
}
// This function loads all records
-(RACSignal *)loadRecords {
NSLog(@"Return all Records");
return [RACSignal return:@[@1, @2, @3]];
}
// This function load infos for the given record
-(RACSignal *)infosForRecord:(id)record {
NSLog(@"Load Infos for Record %@", record);
return [RACSignal return:[NSString stringWithFormat: @"%@ with info", record]];
}
// This function updates the given record
-(RACSignal *)updateRecord:(id)record {
NSLog(@"Update Record: %@", record);
return [RACSignal return:[NSString stringWithFormat: @"Updated - %@", record]];
}
loadRecords
使用所有记录的数组发送一个值。为了然后单独处理这些记录,我们flattenMap
这个并为数组的每个元素发送一个值(使用rac_sequence
)。
然后对每条记录进行直接处理:获取该记录的信息,然后更新该记录。
只要所有记录更新,整个replacePubRecentContact
信号就会完整。
编辑:我写了更详细的解释in my blog