针对同一API,重复网络请求之解决
2020-04-25 本文已影响0人
af4e8a35bc89
在启动应用时机,需从服务器获取特定配置信息,后面其他服务器接口,依赖于此配置信息。
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 标志位,如多次重复请求,有一次请求成功,后面的请求直接使用结果,进行回调。
- 、4.、5. and So on