美文网首页
针对同一API,重复网络请求之解决

针对同一API,重复网络请求之解决

作者: af4e8a35bc89 | 来源:发表于2020-04-25 19:46 被阅读0次

在启动应用时机,需从服务器获取特定配置信息,后面其他服务器接口,依赖于此配置信息。
Sometimes,You Meet 需求Like This ? 处理如是:
其一、在向服务器获取配置的接口请求完成后,向其他请求发送通知,其它请求收到通知,可以执行矣;
其二、先调用获取请求配置的接口,其他接口放在其回调中。这样又会有个问题,其他接口都调用此接口,短时间内多次重复请求服务器。
一种解决方法:
思路:把callback用数组保存,同一时间,只进行一个请求,请求结束后,把结果发给数组中的所有callback。

/*多个线程请求同一个API服务器资源,避免重复请求。*/
typedef void(^LoadServerConfigClosure)(NSData* data);
+(void)loadServerConfigByCompletionBlock:(LoadServerConfigClosure)completionBlock{
    NSString* urlStr = @"https://www.sina.com.cn/";
    @synchronized (self) {//加锁,避免多线程下同时操作,数组被重复创建、添加等问题
        static NSMutableArray* _completeBlocks; //用数组保存回调
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _completeBlocks = [NSMutableArray array];//仅创建一次数组
        });
        
        if (completionBlock) {//每调用一次此函数 就把回调加进数组中
            [_completeBlocks addObject:[completionBlock copy]];
        }
        
        static BOOL isProcceeding = NO; //如果已经在请求了 就不再发出新的请求
        if (isProcceeding == YES) {return;}
        isProcceeding = YES;
        NSURL* url = [NSURL URLWithString:urlStr];
        NSURLSessionTask* task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            @synchronized (self) {//网络请求回调加锁,这已经是另一个线程了。因为异步网络请求将开辟新线程处理任务。
                for (LoadServerConfigClosure block in _completeBlocks) {
                    //遍历回调数组,将结果发送给各调用者
                    block(data);
                }
                [_completeBlocks removeAllObjects];
                isProcceeding = NO;
            }
        }];
        [task resume];
    }
}

思维扩展
1.数据库等异步耗时操作
2.Add Other 标志位,如多次重复请求,有一次请求成功,后面的请求直接使用结果,进行回调。

  1. 、4.、5. and So on

相关文章

网友评论

      本文标题:针对同一API,重复网络请求之解决

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