当前位置: 首页 > 工具软件 > coobjc > 使用案例 >

IOS 阿里开源coobjc 实用场景分析之COPromise

尹臻
2023-12-01

先附上 coobjc 地址
今天先分析一下里面的一个实用功能点,如果有什么分析不对的勿怪。
当看到COPromise实用场景介绍的时候我会毫不犹豫的联想到bolts,
如果大家对bolts不熟悉的看一下(bolts Github)。
我先说一下应用场景介绍吧:
场景1.有一个界面中有3个接口A、B、C,界面在3个接口完成请求后再去对数据进行展示。
场景2.有一个界面中有3个接口A、B、C,接口C依赖接口A 和 B请求返回数据,完成所有接口请求后进行数据展示。
场景3.有一个界面中有3个接口A、B、C,接口 C依赖接口B 接口B 依赖A ,完成所有接口请求后进行数据展示。
以上场景想想是不是很难受,而且脑子里会出现线程操作。
下面我会根据场景进行代码的详细对比,主要是进行传统做法、bolts、coobjc 代码对比。

场景1对比

场景1具体描述 接口A 获取顶部banner 数据,接口B获取最新活动模板数据,接口C 获取猜你喜欢商品数据,3个接口请求完成后进行数据展示。
传统做法:

    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //获取banner数据
        [JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
      
            dispatch_group_leave(group);
        }];
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //获取最新活动模板数据
        [JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
     
            dispatch_group_leave(group);
        }];
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //获取猜你喜欢商品数据
        [JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
    
            dispatch_group_leave(group);
        }];
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    //数据展示
        [weakSelf reloadData];
    });

bolts 方式:

//获取banner数据
-(BFTask *)searchInsBanner{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
        [taskSource setResult:ayBanner];
    }];
    return taskSource.task;
}
 //获取最新活动模板数据
-(BFTask *)searchNewMould{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
        [taskSource setResult:ayMould];
    }];
    return taskSource.task;
}
 //获取猜你喜欢商品数据
-(BFTask *)searchMould{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
        [taskSource setResult:ayMould];
    }];
    return taskSource.task;
}

//调用方式
    [[BFTask taskForCompletionOfAllTasksWithResults:@[[self searchInsBanner],[self searchNewMould],[self searchMould]]] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id _Nullable(BFTask * _Nonnull t) {

        [weakSelf reloadData];
        return nil;
    }];

coobjc 方式:

//获取banner数据
-(COPromise *)fetchInsBanner{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
        [promise fulfill:ayBanner];
    }];
    return promise;
}

 //获取最新活动模板数据
-(COPromise *)fetchNewMould{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
        [promise fulfill:ayMould];
    }];
    return promise;
}

//获取猜你喜欢商品数据
-(COPromise *)fetchMould{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
        [promise fulfill:ayMould];
    }];
    return promise;
}

    co_launch(^{
        NSArray<JLBInsBannerModel *> *ayBanner  = await([self fetchInsBanner]);
        NSArray<JLBInsActivityModel *> *ayNewMould = await([self fetchNewMould]);
        NSArray *ayMould = await([self fetchMould]);
        [self reloadData];
    });

结合以上提供的代码,我们分析其实在这个场景中bolts 和coobjc 的代码实现和可读性都很好,其实这个场景中个人还是推荐bolts的。

场景2对比(和场景3类似这里一起对比)

场景2具体描述 接口A 获取顶部banner 数据,接口B获取最新活动模板数据,接口C 获取猜你喜欢商品数据,接口C 依赖接口A 、B 返回数据然后进行请求,最后进行数据展示。
场景3也是这3个接口,但是B 依赖A、C依赖B,场景2在实用的时候,写法和逻辑一样按照场景3一样可以实现最终结果,那这里我就按照场景3来做对比了。

传统做法,用NSOperationQueue

    //创建队列
    NSOperationQueue *queue=[[NSOperationQueue alloc] init];
    //创建操作
    NSBlockOperation *operation1=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第1次操作,线程:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第2次操作,线程:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第3次操作,线程:%@",[NSThread currentThread]);
    }];
    //添加依赖
    [operation1 addDependency:operation2];
    [operation2 addDependency:operation3];
    //将操作添加到队列中去
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];

bolts 方式:

//获取banner数据
-(BFTask *)searchInsBanner{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
        [taskSource setResult:ayBanner];
    }];
    return taskSource.task;
}
 //获取最新活动模板数据
-(BFTask *)searchNewMould{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
        [taskSource setResult:ayMould];
    }];
    return taskSource.task;
}
 //获取猜你喜欢商品数据
-(BFTask *)searchMould{
    BFTaskCompletionSource * taskSource = [BFTaskCompletionSource taskCompletionSource];
    [JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
        [taskSource setResult:ayMould];
    }];
    return taskSource.task;
}

//调用方式
  [[[[self searchInsBanner] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
        return [self searchNewMould];
    }] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
        return [self searchMould];
    }] continueWithBlock:^id _Nullable(BFTask * _Nonnull t) {
        [weakSelf reloadData];
        return nil;
    }];

coobjc 方式:

//获取banner数据
-(COPromise *)fetchInsBanner{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchInsBanner:^(NSArray<JLBInsBannerModel *> *ayBanner) {
        [promise fulfill:ayBanner];
    }];
    return promise;
}

 //获取最新活动模板数据
-(COPromise *)fetchNewMould{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchNewMould:^(NSArray<JLBInsActivityModel *> *ayMould) {
        [promise fulfill:ayMould];
    }];
    return promise;
}

//获取猜你喜欢商品数据
-(COPromise *)fetchMould{
    COPromise *promise = [COPromise promise];
    [JLBInstitutionApi searchMould:@"0" page:self.nStartPos complete:^(NSArray *ayMould) {
        [promise fulfill:ayMould];
    }];
    return promise;
}

    co_launch(^{
        NSArray<JLBInsBannerModel *> *ayBanner  = await([self fetchInsBanner]);
        NSArray<JLBInsActivityModel *> *ayNewMould = await([self fetchNewMould]);
        NSArray *ayMould = await([self fetchMould]);
        [self reloadData];
    });

你们没有看错这里coobjc 方式始终没有变,因为有await 你可以自由组合其执行顺序,感觉方便了很多,自己写上注释,那么业务代码逻辑一目了然。

 类似资料: