值完成错误

错误处理真的很难 ,可能重新读取一个文件可能出错,重新读取成功后,修改内容再去保存可能出错。各种的错误都可能发生,使开发变得很难。

Objective-C的错误处理

写过Objective-C的朋友们都知道,在Objective-C中处理错误非常麻烦:

  NSError *错误; 
id json = [NSJSONSerialization JSONObjectWithData:data,options:0,error:&error];
如果(json){
//解析成功,继续处理
}其他{
//出现错误,处理错误
}

最重要的逻辑是处理解析JSON成功的事情,但考虑到可能出现错误,不得不写很多的代码处理错误。经常可能这种错误处理的代码会写的很多,难以想到起初的逻辑是什么,为此更多时候都会选择忽略错误,直接在error参数中初始化一个nil,从而简化代码的逻辑。

Swift的错误处理

Swift在处理错误时,采用了do catch的方案。

当然Objective-C也有类似的方案,只是根本就没有人用。

在定义一个可能出现错误的方法中加入一个throws的标记就可以了。

 公共类func JSONObjectWithData(data:NSData,选项opt:NSJSONReadingOptions)抛出-> AnyObject 

处理错误的时候代码会写成这个样子:

 做{ 
让json =试试NSJSONSerialization.JSONObjectWithData(数据,选项:NSJSONReadingOptions.AllowFragments)
打印(json)
} {
打印(错误)
}

参见Objective-C,最强大的地方就是可以在这里调用多个可能引发错误的方法。

 做{ 
让数据=尝试NSData(contentsOfFile:路径,选项:NSDataReadingOptions())
让json =试试NSJSONSerialization.JSONObjectWithData(数据,选项:NSJSONReadingOptions.AllowFragments)
打印(json)
} {
打印(错误)
}

从一个文件中读取数据(NSData),再将其解析成JSON,这两个步骤都可能出现错误,幸运的是可以将这些错误统一起来处理,上面的两个尝试中错误,都将走到catch的闭包中。

然而异步的错误处理呢?

处理异步下的错误情况

仍然是Alamofire的例子:

  request(.GET,“ https://github.com/fluidicon.png”) 
.responseData {(回应)
切换response.result {
案例。成功(让数据):
打印(数据)
案例。失败(让错误):
打印(错误)
//如何抛出
}
}

又是一个无法完成的事情。Observable可以很好的完成这件事情。

可观察的处理错误

在进行各种操作变换时,实际上,存在某些场景下一步错误完成 ,例如在下面依次变换的过程:

其中:

表示传递的值。

表示出现了某种错误(而无法继续)。

表示整个事件流已经结束。

上面这一变换过程描述的是先乘2 ,再用48除以该值两个步骤, 不幸的是,在最开始对准一个0 ,会导致错误产生,即除数不能为0。

 枚举ComputeError:ErrorType { 
案例区分
}
[3,4,0] .toObservable()
.map {$ 0 * 2}
.map {value-> Int in
保护值!= 0其他{
抛出ComputeError.divisionByZero
}
返回48 /值
}
.subscribe {事件在
切换事件{
case .Next(让值):
print(“结果:\(值)”)
大小写.Error(let error):
打印(“错误:\(错误)”)
案例。完成:
打印(“完成”)
}
}
.addDisposableTo(disposeBag)

需要抛出错误就只需要调用throw ComputeError.divisionByZero,所有的错误都会执行到subscription中的case .Error(错误):。

一个可以观察到的可以传递值,错误,结束两种情况。在异步的处理中也非常轻松,只需要调用观察者(Observer)的onError方法,将错误信息传递下去。

  Observable  .create {(观察者)在 
让downloadImage = request(.GET,“ https://github.com/fluidicon.png”)
.responseData {(回应)
切换reponse.result {
案例。成功(让数据):
rator.onNext(数据)
案例。失败(让错误):
rator.onError(错误)
}
rator.onCompleted()
}
返回AnonymousDisposable {
downloadImage.cancel()
}
}

在请求结果返回的时候根据不同的情况,调用观察者的onNext或onError方法。这样一来,错误处理就变得很优雅了,有错误的时候调用onError即可。

总结

特别是异步的错误处理变得异常麻烦,Rx提供了onError的方法,为开发者提供了一个很优雅的错误处理方案。