美文网首页
问题:如何处理异步的网络请求?

问题:如何处理异步的网络请求?

作者: 姜小舟 | 来源:发表于2022-04-20 17:41 被阅读0次

在开发中我们常常会遇到在一个界面中需要异步请求多个接口,通过不同接口的返回数据刷新界面不同控件的需求。这种情况下有两种选择,一种是 依次请求多个接口,分别拿到数据 这种方式有两种方法实现:1: 接口回调嵌套(容易造成代码金字塔,写法low)2:管理多线程 使异步的请求操作变成依次执行。 依次请求接口的方式很容易造成用户在当前界面请求时间过长而影响体验,这就需要我们 并发的发起多个异步请求了,但有时候我们界面刷新时 不同界面间的数据存在 关联,我们得在所有请求完成后才能 统一 对界面刷新或者其它操作, 下面我简单介绍使用GCD 使 监听异步请求全部完成 和 异步请求依次进行 的方式。

1. 监听异步请求全部完成 再完成刷新界面等操作

先上代码:

 dispatch_group_t group = dispatch_group_create();//创建队列组

 dispatch_group_enter(group); //队列组中加入一个异步操作
  //网络请求
 [[HttpTool sharedJsonClient]   requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
        NSLog(@"请求第一个完成");

        //队列组中移除一个异步操作
        dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
    [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
        NSLog(@"请求第二个完成");
        dispatch_group_leave(group);
    }];
    
    dispatch_group_enter(group);
    [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
        NSLog(@"请求第三个完成");
        dispatch_group_leave(group);
    }];
    
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"请求全部完成 w回到主线程了");
    });

使用了CGD 中队列组方式,通过发起请求时 加入一个异步事件到队列组,请求完成后 将其移除, 最终监听队列组中无操作时 即为所有请求事件已完成。 要注意的一点是 网络请求本身就是异步的操作, 所以不能写成:

    dispatch_async(queue, ^{
        [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
            NSLog(@"请求第一个完成");
            dispatch_semaphore_signal(semaphore); //信号量 +1
        }];
    }

2. 使异步的网络请求依次进行

    //新建一个串行(并行 都可以)队列, 在该 队列中对 所有 的网络请求做操作
    dispatch_queue_t queue = dispatch_queue_create("sdsdsdsd", DISPATCH_QUEUE_SERIAL);
    //创建信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); //初始为 0
    NSLog(@"开始执行3");
    dispatch_async(queue, ^{

        NSLog(@"开始执行1");
        [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
            NSLog(@"请求第一个完成");
            dispatch_semaphore_signal(semaphore); //信号量 +1
        }];
        //信号量为0 时不 执行  (如果信号量 不为 0 时才往下执行并且 信号量 -1)
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

        NSLog(@"开始执行2");
        [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
            NSLog(@"请求第二个完成");
            dispatch_semaphore_signal(semaphore); //信号量 +1
        }];
        //信号量为0 时不 执行  (如果信号量 不为 0 时才往下执行并且 信号量 -1)
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);


        NSLog(@"开始执行3");
        [[HttpTool sharedJsonClient] requestJsonDataWithPath:newUrlString andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
            NSLog(@"请求第三个完成");
            dispatch_async(queue, ^{
                 dispatch_semaphore_signal(semaphore); //信号量 +1
            });

        }];

        //信号量为0 时不 执行  (如果信号量 不为 0 时才往下执行并且 信号量 -1)
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"在当前线程中继续执行");
    });

需要注意的事项是:

  • 如果在 主队列中 做 信号量的加减和wait等操作 ,dispatch_semaphore_wait 方式会阻塞当前线程(主线程),而网络请求的回调默认是回到主线程中 处理事件的, 由此会导致 主线程中 dispatch_semaphore_signal(semaphore); 方法不会执行,造成主线程死锁。 所以,只能新建一个 串行或者 并行 队列(新建队列的时候会开一条线程管理事件) 对 网络请求操作 做管理 (不能在主队列)
  • 使用AFN网络请求操作会自动开启子线程执行,而请求完成后的操作会自动回到主线程。

相关文章

  • 网络编程和数据处理

    网络编程 主要是学会如何请求网络数据,基本使用Java中的方法。(网络请求必须异步处理) 数据处理 XML格式SA...

  • 问题:如何处理异步的网络请求?

    在开发中我们常常会遇到在一个界面中需要异步请求多个接口,通过不同接口的返回数据刷新界面不同控件的需求。这种情况下有...

  • OkHttp 版源码分析

    分析的问题 Call如何处理同步和异步请求; Dispatcher如何管理请求任务; OkHttp拦截器链; 连接...

  • 微信小程序微信开放API

    开放接口: 设备 API 列表: 多数 API 的回调都是异步,你需要处理好代码逻辑的异步问题。 网络请求API ...

  • Android常用框架

    网络请求 OkHttp NoHttp(国内作者) Retrofit 异步处理 RxJava RxAndroid 图...

  • Promise

    1 异步事件的处理 那什么时候我们会来处理异步事件呢?一种很常见的场景应该就是网络请求了。我们封装一个网络请求的函...

  • Antd Pro 与后端交互的几种场景(持更)

    Antd Pro如何处理异步请求? Antd Pro的异步请求用的是Dva,而Dva的异步又是在fetch的基础上...

  • 异步Servlet 特性

    异步Servlet 本篇主要讲解 如何使用 异步Servlet的处理请求,并且演示 同步Servlet和异步Ser...

  • 网络不好时异步。 请求处理问题。

    如果网络不好,请求还在处理的时候,用户back关掉页面。 两种处理方法。 1判断页面是否销毁,如果销毁了,不往下执...

  • 基于FutureBuilder通用网络请求界面封装

    基于FutureBuilder通用网络请求界面封装 Dart异步编程Future 在Dart中,处理异步有两种方式...

网友评论

      本文标题:问题:如何处理异步的网络请求?

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