ios - 利用afnetworking3.0通过for循环发送请求,如何保证接收到数据的顺序和发送请求的顺序一致?

 版中凌菱 发布于 2022-10-28 11:43

利用AFN3.0进行网络请求,要发送的参数在一个数组里,每次取数组中的一条数据设置参数发送请求,

我通过for循环遍历数组并设置参数发送请求,将网络请求返回的数据添加到一个新的数组中,

发现不是每次请求返回的数据的顺序是一样的,功能需求返回数据的排序必须跟发送请求的顺序是一样的,

求问有什么方法保证前一次请求返回数据之后再发送下一次请求?

非常感谢,万分感谢!!!!

/**
 *  加载订单数据,设置控件位置
 */
- (void)loadOrderData {
        NSString *userID = [[NSUserDefaults standardUserDefaults] stringForKey:@"GOId"];
        NSDictionary *dict = @{
                               @"GOId" : userID,
                               };
        // 将字典转为json
        NSDictionary *params = [ELHOCToJson ocToJson:dict];
        
        NSString *URL = [NSString stringWithFormat:@"%@RealtimeOrder_getROListCon12345.action", ELHBaseURL];
        
        
        __weak typeof(self) weakSelf = self;
        [self.manager POST:URL parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            weakSelf.ELHOrderArray = [ELHOrderModel mj_objectArrayWithKeyValuesArray:responseObject];
            

            
            // 获取订单编号
            for (int i = 0; i < weakSelf.ELHOrderArray.count; i++) {
                ELHOrderModel *model = weakSelf.ELHOrderArray[i];
                
                [weakSelf.ELHOrderNumArray addObject:model.ROBM];
                
            }
            

            // 根据获取到的订单编号加载订单详情列表
            if (weakSelf.ELHOrderNumArray != nil) {
                dispatch_queue_t conCurrentQueue = dispatch_queue_create("order", NULL);
                for (NSString *ROBM in weakSelf.ELHOrderNumArray) {
                    dispatch_barrier_async(conCurrentQueue, ^{
                        // 加载订单详情列表
                        [self loadOrderDetailData:ROBM];
                    });
                }
            }
            
            
       
            
            // 刷新数据
            [orderVC.tableView reloadData];
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            NSLog(@"%@", error);
        }];
    
}



/**
 *   加载订单详情列表
 */
- (void)loadOrderDetailData:(NSString *)ROBM {
    NSDictionary *dict = @{
                           @"ROBM" : ROBM,
                           };
    
    // 字典转json
    NSDictionary *params = [ELHOCToJson ocToJson:dict];
    
    NSString *URL = [NSString stringWithFormat:@"%@OrderPrice_getOPListByROBM.action", ELHBaseURL];
    
    __weak typeof(self) weakSelf = self;
    [self.manager POST:URL parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {       
    
        // 将获取到的订单详情数据逐个添加到数组中
        [weakSelf.ELHOrderDetailArray addObject:[ELHOrderDetailModel mj_objectArrayWithKeyValuesArray:responseObject]];
        ELHOrderTableViewController *orderVC = weakSelf.childViewControllers.firstObject;
        
        orderVC.orderDetailArray = weakSelf.ELHOrderDetailArray;
        
        // 刷新数据
        [orderVC.tableView reloadData];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"%@", error);
    }];
}
4 个回答
  • 新写了一个辅助类,希望可以帮到你。
    https://github.com/sunbohong/SunOrderArr...

    2022-10-29 18:54 回答
  • 使用GCD dispatch_barrier_async 这个方法可以,但是队列必须是自己创建的,而不能是全局队列

    dispatch_queue_t conCurrentQueue = dispatch_queue_create("test", NULL);
    NSArray *numAry = @[@"1",@"3",@"4",@"2",];
    
    for (NSString *str in numAry) {
        
            dispatch_barrier_async(conCurrentQueue, ^{
                
                //这里写网络请求
            });
    }
    2022-10-29 18:54 回答
  • 你的问题类似这个 https://segmentfault.com/q/1010000004632... 如果你只是希望保证返回结果的顺序,就并不一定需要所有的请求串行的进行。

    另外,如果你非要串行的进行请求的话,可以新建一个 NSOperationQueue,并把它的 maxConcurrentOperationCount 设置为 1, 然后把你的每个请求顺序地加入到这个 NSOperationQueue 里去。

    2022-10-29 18:57 回答
  • 按你的做法当然不一定一样了,有些请求可能是后发出的,但返回比较快,就先返回了。

    不清楚你的需求是不是一定要依次请求。比如像一次上传 10 张图片,然后把返回的 url 按顺序塞到一个数组里这种需求,我们一般都是分几个线程同时请求的,而不是一张一张依次传的。这样要快很多。

    如果你是要保证依次请求的话,就要把下一次请求的发送放在上一次请求结束之后。比如:

    - (void)requestWithArray:(NSArray*)array index:(NSInteger)index completion:(SomeBlock)completion {
        if (index >= array.count) {
            if (completion) {
                completion();
            }
            return;
        }
        
        AFHTTPRequestOperationManager* manager = [self httpsRequestManager];
        NSDictionary* params = @{"key":array[index]};
        __weak typeof(self) weakSelf = self;
        [manager GET:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            [weakSelf requestWithArray:array index:index + 1 completion:completion];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            // handle failure
        }];

    大概是这意思,明白了吗?

    但是像上传 10 张图片那种,就是只要保证结果顺序正确,不需要请求一个一个串行的话,应该用[AFURLConnectionOperation batchOfRequestOperations:]。最好优先考虑下这样是否能满足你的需求。

    2022-10-29 19:08 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有