转载

为什么我推荐在网络请求回调处理分成两部分

《Effective Objective-C 2.0》这本书中第 39 条:用 handler 块降低代码分散程度,建议“使用同一个块来处理成功与失败情况”,在实习的阶段刚好遇到这个情况,所以浅显的论述一下自己的观点,希望能有个抛砖引玉的效果。

本书中对两种回调处理的分析

成功情况和失败情况用两个块分别处理

API 如下:

EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHander:^(NSData *data) {       // Handler success }             failureHandler:^(NSError *error) {      // Handler failure }]; 

优点:

  • 不同情况分开写,代码更易读懂
  • 还可以根据具体需要,把处理失败情况或者成功情况所用的代码省略

成功情况和失败情况处理全部放在一个块

API 如下:

EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHander:^(NSData *data, NSError *error) {       if (error) {           // Handle failure       } else {          // Handle success       } }]; 

优点:

  • 在传入错误信息时,可以把数据也传进来
  • 可以根据问题作适当处理,并利用已经获得的数据做些事情
  • 调用 API 的代码可能会在处理成功响应的过程中发现错误

根据自己的具体使用经验来分析我为什么推荐前者:

分离网络请求成功和失败处理

先给出我司在网络请求回调的处理方式(大概如下):

^(DQKDataModel *dataModel, DQKErrorModel *errorModel, NSError *error) {        // Handle … } 

Response 的 JSON 数据大概如下:

{     data =     {      topic  = “天气不错”;     };     respcd = “00”;     respmsg = “数据获取成功”; }  

回调的代码块就是上面的样子,分别是成功返回数据信息(data)、业务逻辑信息(respcd ,respmsg)、网络请求错误信息。一个代码块,数据可以统一处理。

我们一般不会去在 GET POST 中,获得很大的数据的 Response ,所以作者提到的这种数据一半就没了的情况基本是不会有的,我们从 业务处理网络处理 两个情况来分析。

这里业务逻辑信息是指如登录密码错误,没有权限发帖等逻辑。

从网络请求层面分析,如果网络有问题,或者服务器处理出现错误等等,这个时候可能会出现错误 404 ,500 之类的情况,此时就不会有 JSON 数据的返回,那也就不会有返回数据信息,业务逻辑信息,因为这两个是同时在 JSON 中一起返回的。网络回调的层次应该如下所示:

成功返回数据信息 业务逻辑信息
网络请求错误信息

二者并没有什么可联系的关系,有数据一般就没有网络错误信息,没有数据一般就没有网络错误信息。

执行成功的代码就必定不执行失败的代码,反之亦然

两个块的时候,一个块专注处理成功情况,一个块专注网络错误,不需要再去判断有那个数据,没有那个数据,会处理成功的代码块就一定是有数据的,会处理错误信息的代码就一定是网络请求中出现了某些问题。

同时这里还减少了一层 鞭尸金字塔 ,更方便代码的维护和 Review 。

这里说的鞭尸金字塔就是类似如下代码:

if (condition) {  if (condition) {   if (condition) {    if (condition) {     statements    } else if (expression) {     statements    } else {     statements    }   }  } else if (expression) {   statements  } else {   statements  } } else {  statements }  
 ## 业务失败放在数据中           那么我们该怎么解决这种既需要处理网络请求错误,也需要处理业务逻辑错误呢?        我的方法如下:        ```Objective-C ^(DQKDataModel *dataModel) {        if (dataModel.error) {         // Handler data error        } else if (dataModel.data) {        // Handler data        } } failureHandler:^(NSError *error) {      // Handler failure } 

对返回的数据处理生成两个属性,一个是业务错误信息,一个是数据成功信息,相比之前的处理可能会清晰一点。

如果您对网络请求的封装的有更好的想法、理解,欢迎大家一起微博上讨论(暂未开通博客评论功能,见谅见谅)。

正文到此结束
Loading...