美文网首页iOS基本功
频繁的Http请求,如何取消之前已经发送的Http请求?

频繁的Http请求,如何取消之前已经发送的Http请求?

作者: 书写不简单 | 来源:发表于2019-01-07 10:49 被阅读134次

    问题转载:

    我有一个TextField,无论什么时候当我输入字符的时候,我appending这个字符到我的url,然后发送一次请求,我现在需要取消之前的请求。例如当我输入“shampoo”的时候,我会触发7次代理方法,也就是我会触发七次不同的网络请求,那么有一个问题,这七次发出的请求,响应的顺序可不是你想的按顺序返回的,例如发送的是1234567,那么返回数据很有可能是1234576,这样导致最后需要的结果不是“7”,而是“6”。那么看看我是如何解决的以及遇到坑的!!!

    • 不要initialize a new AFHTTPSessionManager object everytime 一定要把manager用成全局的

    • 把请求返回的task对象丢进数组,下次触发的时候把遍历数组,把之前的所有任务[task cancel]

    // somewhere in your class, let's say in ViewDidLoad you should init the AFHTTPSessionManager object
    - (void)viewDidLoad {
        [super viewDidLoad];
     
        /// create the AFHTTPSessionManager object, we're gonna use it in every request
        self.manager = [[AFHTTPSessionManager alloc] init];
        self.manager.responseSerializer = [AFJSONResponseSerializer serializer];
     
        /// create an array that is going to hold the requests task we've sent to the server. so we can get back to them later
        self.arrayOfTasks = [NSMutableArray new];
        /// discussion:
        /// an array holds multiple objects. if you just want to hold a ref to the latest task object
        /// then create a property of NSURLSessionDataTask instead of NSMutableArray, and let it point to the latest NSURLSessionDataTask object you create
     
    }
     
     
    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;{
        /// your code goes here
        /// .....
        /// .....
        /// .....
        /// .....
        /// till we reach
        if(stringLength>=3){
            /// cancel all previous tasks
            [self.arrayOfTasks enumerateObjectsUsingBlock:^(NSURLSessionDataTask *taskObj, NSUInteger idx, BOOL *stop) {
                [taskObj cancel]; /// when sending cancel to the task failure: block is going to be called
            }];
     
            /// empty the arraOfTasks
            [self.arrayOfTasks removeAllObjects];
     
            /// init new task
            NSURLSessionDataTask *task = [self.manager GET:urlString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject){
               /// your code
            }failure:^(NSURLSessionDataTask *task, NSError *error){
               /// your code
            }];
     
            /// add the task to our arrayOfTasks
            [self.arrayOfTasks addObject:task];
        }
        return YES;
    }
    
    

    注意:
    这里的task cancel亲测确实能把网络请求cancel掉,可以看下面的log,记住一点,这里cancel之后不代表就不回调了,只是会回调到error的那个block里面,各位需要信息的可以测试下,在error打个断点就能调试出来了

    // 查看网络任务的状态
    [articleInterface.articleArrayTask enumerateObjectsUsingBlock:^(NSURLSessionDataTask *taskObj, NSUInteger idx, BOOL *stop) {
        DDLogVerbose(@"当前的文章删除前网络任务状态是==================>>>>>%ld",taskObj.state);
        [taskObj cancel]; /// when sending cancel to the task failure: block is going to be called
        DDLogVerbose(@"当前的文章删除后网络任务状态是==================>>>>>%ld",taskObj.state);
    }];
    typedef NS_ENUM(NSInteger, NSURLSessionTaskState) {
        NSURLSessionTaskStateRunning = 0,                     /* The task is currently being serviced by the session */
        NSURLSessionTaskStateSuspended = 1,
        NSURLSessionTaskStateCanceling = 2,                   /* The task has been told to cancel.  The session will receive a URLSession:task:didCompleteWithError: message. */
        NSURLSessionTaskStateCompleted = 3,                   /* The task has completed and the session will receive no more delegate notifications */
    } NS_ENUM_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0);
    
    
    image

    相关文章

      网友评论

        本文标题:频繁的Http请求,如何取消之前已经发送的Http请求?

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