美文网首页
使用GCD的group来控制网络请求顺序

使用GCD的group来控制网络请求顺序

作者: Corbin___ | 来源:发表于2020-02-15 15:58 被阅读0次

使用GCD的group来控制网络请求顺序

同时发起多个网络请求,等都完成后,再统一处理

dispatch_group_notify会等dispatch_group_async的任务都执行完,再执行

- (void)group1Use
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"任务一完成");
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"任务二完成");
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"都完成了");
    });
}

如果NSLog(@"任务一完成");也是异步的,那么就会先输出“都完成了”,这个更符合实际的网络请求的场景,dispatch_group_async中放的是一个网络请求,我们要的“都完成了”,应该是网络请求都回调了才输出"都完成了"

- (void)group2Use
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
            NSLog(@"任务一完成");
        });
    });
    
    dispatch_group_async(group, queue, ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
            NSLog(@"任务二完成");
        });
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"都完成了");
    });
}

这时候的输出结果为:

都完成了
任务一完成
任务二完成

显然这不是我们想要的效果,因此对于这种情况,我们需要用到dispatch_group_enter,dispatch_group_leave

- (void)group3Use
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"任务一完成");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"任务二完成");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"都完成了");
    });
}

这就达到我们的预期了

任务一完成
任务二完成
都完成了

需要注意一点,这里的任务一和任务二不是顺序执行的,因为我模拟的都是延迟2s后执行

dispatch_group_enterdispatch_group_leave 一般是成对出现的, 进入一次,就得离开一次。也就是说,当离开和进入的次数相同时,就代表任务组完成了。如果enter比leave多,那就是没完成,如果leave调用的次数多了, 会崩溃的;

dispatch_group_leavedispatch_group_enter不能在同一个线程,不然会死锁

其实我们上面的group3Use的方法就是应用于同时多个发起多个网络请求,等都完成后,再统一处理

比如:我进入一个app某个页面,这个页面要显示的数据,需要通过5个接口获取,那么我们就可以用这种方式,同时发起5个请求,等请求都回调完成了,再统一拿数据刷新界面

依次进行网络请求

介绍一个函数dispatch_group_wait,这个函数会卡住线程,直到group内的任务执行完。

所以我们可以利用这个函数,来达到依次进行网络请求

- (void)group4Use
{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    // 注意,故意将这个任务一的延迟时间调成4s,比任务二多2s
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"任务一完成");
        dispatch_group_leave(group);
    });
    
    // 现在group内的任务只有任务一,所以这时候会卡住线程,等任务一执行完毕,这个类似信号量,所以dispatch_group_leave和dispatch_group_enter不能在同一个线程,不然会死锁
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    dispatch_group_enter(group);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"任务二完成");
        dispatch_group_leave(group);
    });
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"都完成了");
    });
}

输出:

任务一完成
任务二完成
都完成了

结语

/ >。< star这个项目支持下,今年有空会从笔记中整理一些东西出来

文章代码

相关文章

网友评论

      本文标题:使用GCD的group来控制网络请求顺序

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