美文网首页
异步发起多个网络请求 同步问题

异步发起多个网络请求 同步问题

作者: xxttw | 来源:发表于2023-06-16 17:58 被阅读0次
多个异步任务, 网络请求之间互相依赖, 请求本身也是异步, 如何让所有网络请求数据返回后才继续执行任务

1.到这里其实有两层异步, 首先是任务是异步执行的, 任务里的代码只要执行完毕, 任务就算执行完成
2.网络请求也是异步执行, 请求的数据不会立刻返回, 我们要求的是 请求的数据返回之后才算任务结束
3.到这里应该大概知道问题点了 show me the code

未同步结果的情况
-(void)test1
{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    
    NSURLSession *session = [NSURLSession sharedSession];

    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求1 返回数据");
            

        }];
        [task resume];
        NSLog(@"请求1 ");
    });
    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求2 返回数据");
            

        }];
        [task resume];
        NSLog(@"请求2 ");
    });
    
    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求3 返回数据");
            

        }];
        [task resume];
        NSLog(@"请求3 ");
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"请求全部完成");
    });
}
2022-12-20 12:02:18.600424+0800 异步多个网络请求同步返回问题[56505:9936064] 请求3 
2022-12-20 12:02:18.600425+0800 异步多个网络请求同步返回问题[56505:9936062] 请求1 
2022-12-20 12:02:18.600427+0800 异步多个网络请求同步返回问题[56505:9936063] 请求2 
2022-12-20 12:02:18.600508+0800 异步多个网络请求同步返回问题[56505:9936063] 请求全部完成
2022-12-20 12:02:18.703725+0800 异步多个网络请求同步返回问题[56505:9936062] 请求2 返回数据
2022-12-20 12:02:18.742708+0800 异步多个网络请求同步返回问题[56505:9936064] 请求1 返回数据
2022-12-20 12:02:18.743819+0800 异步多个网络请求同步返回问题[56505:9936069] 请求3 返回数据
  • 从代码打印结果来看 请求1.2.3 只要执行完毕, 就打印了全部完成, 这不符合预期
  • 我们要的是请求1.2.3 数据都返回后才算 全部完成
  • 我们可以通过 dispatch_group_enter(group)dispatch_group_leave(group)更加精准的控制
    简单来说dispatch_group_enter 就是 对group内部计数 + 1, dispatch_group_leave 就是对计数-1, 有点类似于retain 和 release, 它们是成对出现, 以前的做法是自己维护一个计数, 在对比计数和总数是否匹配, 匹配就相当于网络请求全部完成, 使用dispatch_group_enter看起来会更加规范
-(void)test2
{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    
    NSURLSession *session = [NSURLSession sharedSession];

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求1 返回数据");
            dispatch_group_leave(group);
            
        }];
        [task resume];
        NSLog(@"请求1 ");
    });
    dispatch_group_enter(group);

    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求2 返回数据");
            dispatch_group_leave(group);

        }];
        [task resume];
        NSLog(@"请求2 ");
    });
    
    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求3 返回数据");
            dispatch_group_leave(group);


        }];
        [task resume];
        NSLog(@"请求3 ");
    });
    
    dispatch_group_notify(group, queue, ^{
        NSLog(@"请求全部完成");
    });
}
2022-12-20 12:13:57.242873+0800 异步多个网络请求同步返回问题[58688:9949703] 请求1 
2022-12-20 12:13:57.242875+0800 异步多个网络请求同步返回问题[58688:9949705] 请求3 
2022-12-20 12:13:57.242877+0800 异步多个网络请求同步返回问题[58688:9949709] 请求2 
2022-12-20 12:13:57.353102+0800 异步多个网络请求同步返回问题[58688:9949709] 请求3 返回数据
2022-12-20 12:13:57.393535+0800 异步多个网络请求同步返回问题[58688:9949704] 请求2 返回数据
2022-12-20 12:13:57.403210+0800 异步多个网络请求同步返回问题[58688:9949708] 请求1 返回数据
2022-12-20 12:13:57.403299+0800 异步多个网络请求同步返回问题[58688:9949703] 请求全部完成
多个异步任务, 网络请求之间互相依赖, 请求本身也是异步, 比如c依赖b, b依赖a 可以使用dispatch_semaphore_t
-(void)test3
{
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
    
    NSURLSession *session = [NSURLSession sharedSession];

    
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求a 返回数据");
            dispatch_semaphore_signal(semaphore);
        }];
        [task resume];
        NSLog(@"请求a");
    });
    

    dispatch_async(queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求b 返回数据");
            dispatch_semaphore_signal(semaphore);

        }];
        [task resume];
        NSLog(@"请求b ");
    });
    
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"请求c 返回数据");
            dispatch_semaphore_signal(semaphore);


        }];
        [task resume];
        NSLog(@"请求c ");
    });
}
2022-12-20 12:27:55.905315+0800 异步多个网络请求同步返回问题[61308:9965813] 请求a 
2022-12-20 12:27:56.013479+0800 异步多个网络请求同步返回问题[61308:9965819] 请求a 返回数据
2022-12-20 12:27:56.013689+0800 异步多个网络请求同步返回问题[61308:9965814] 请求b 
2022-12-20 12:27:56.023961+0800 异步多个网络请求同步返回问题[61308:9965814] 请求b 返回数据
2022-12-20 12:27:56.024199+0800 异步多个网络请求同步返回问题[61308:9965815] 请求c
2022-12-20 12:27:56.033318+0800 异步多个网络请求同步返回问题[61308:9965813] 请求c 返回数据
  • 总结来说就使用下面两种来解决
    1.dispatch_group_enter(), dispatch_group_level
    2.dispatch_semaphore_t

iOS 多个异步网络请求全部返回后再执行具体逻辑的方法

相关文章

  • 网络异步请求同步、顺序处理

    一、异步网络请求按顺序请求(信号量) 打印结果 二、多个网络异步请求最后同步(Group) 打印结果 三、多个网络...

  • 网络协议

    网络请求分为4类:GET同步请求GET异步请求POST同步请求POST异步请求 同步网络请求步骤: 1:创建网址字...

  • OkHttp源码(一)

    同步请求示例 异步请求示例 同步和异步调用只有在最后发起请求时有差别,前面构造OkHttpClient ,Requ...

  • OkHttp源码之同步、异步的区别

    对于okhttp来说,大家都知道有同步和异步两种模式,所谓同步就是在发起请求的线程完成整个网络的连接传输过程,异步...

  • 同步和异步、阻塞和非阻塞

    关于同步和异步 同步和异步其实指:请求发起方对消息结果的获取是主动发起的,还是被动通知的。如果请求方对结果的获取是...

  • 关于多个网络请求同步的一些总结

    等待多个并发请求同步回调 例如同时发起网络请求A,网络请求B,网络请求C,需等待A,B,C都返回了才进行回调。曾经...

  • unity 网络请求(异步和同步)

    1.网络请求(同步请求) 2.网络请求(异步请求) 3——256加密

  • BIO,NIO,AIO

    同步、异步、阻塞、非阻塞 同步与异步 同步: 同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。 异步...

  • Android okHttp网络请求之Get/Post请求

    Android okHttp网络请求之Get/Post请求 异步同步

  • iOS网络NSURLConnection和NSURLSessio

    HTTP通信过程 NSURLConnection发送网络请求 block 方式 发送同步请求发送同步请求 发送异步...

网友评论

      本文标题:异步发起多个网络请求 同步问题

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