Swift - 方法链接
Swift - Method chaining
我想在我的 swift
代码中实现方法链接,很可能是 Alamofire
方法。例如,如果我必须像下面那样使用我的函数
getListForID(12).Success {
// Success block
}. Failure {
// Failure block
}
如何创建函数 getListForID
?
为了理解发生了什么,重写代码时不使用 "convenience" 语法会有所帮助,当闭包是函数的最后一个参数时,它可以让您省略括号:
getListForID(12)
.Success( { /* Success block */ } )
.Failure( { /* Failure block */ } )
这使得API背后的代码结构更加清晰:
getListForID
的 return 值必须是一个对象
- 对象必须有两个函数
Success
和 Failure
*
Success
和Failure
都需要带一个闭包类型的参数
Success
和Failure
都需要returnself
* 对象可能只有 Success
函数,而 return 一个具有单个 Failure
函数的不同对象,但是你将无法重新排序 Success
和 Failure
处理程序,或完全删除 Success
处理程序。
为了扩展 and 提出的要点——这里有一个小示例,说明如何使用您想要的方便语法实现请求函数以获取成功和失败闭包。
首先,您必须定义一个新的 class 来表示 'result handler'。这就是您的 success
和 failure
函数将传递的内容,允许您添加多个尾随闭包来构成您的完成块逻辑。你会希望它看起来像这样:
class ResultHandler {
typealias SuccessClosure = RequestHandler.Output->Void
typealias FailureClosure = Void->Void
// the success and failure callback arrays
private var _successes = [SuccessClosure]()
private var _failures = [FailureClosure]()
/// Invoke all the stored callbacks with a given callback result
func invokeCallbacks(result:RequestHandler.Result) {
switch result {
case .Success(let output): _successes.forEach{[=10=](output)}
case .Failure: _failures.forEach{[=10=]()}
}
}
// remove all callbacks – could call this from within invokeCallbacks
// depending on the re-usability of the class
func removeAllCallbacks() {
_successes.removeAll()
_failures.removeAll()
}
/// appends a new success callback to the result handler's successes array
func success(closure:SuccessClosure) -> Self {
_successes.append(closure)
return self
}
/// appends a new failure callback to the result handler's failures array
func failure(closure:FailureClosure) -> Self {
_failures.append(closure)
return self
}
}
这将允许您定义要在完成时执行的多个成功或失败闭包。如果您实际上不需要多个闭包的容量,那么您可以通过剥离数组来简化 class —— 而是只跟踪最后添加的成功和失败完成块。
现在您所要做的就是定义一个函数,该函数生成一个新的 ResultHandler
实例,然后执行给定的异步请求,并在完成时调用 invokeCallbacks
方法:
func doRequest(input:Input) -> ResultHandler {
let resultHandler = ResultHandler()
doSomethingAsynchronous(resultHandler.invokeCallbacks)
return resultHandler
}
现在你可以这样称呼它了:
doRequest(input).success {result in
print("success, with:", result)
}.failure {
print("fail :(")
}
唯一需要注意的是您的 doSomethingAsynchronous
函数必须将其完成块分派回主线程,以确保线程安全。
完整项目(添加了使用示例):https://github.com/hamishknight/Callback-Closure-Chaining
我想在我的 swift
代码中实现方法链接,很可能是 Alamofire
方法。例如,如果我必须像下面那样使用我的函数
getListForID(12).Success {
// Success block
}. Failure {
// Failure block
}
如何创建函数 getListForID
?
为了理解发生了什么,重写代码时不使用 "convenience" 语法会有所帮助,当闭包是函数的最后一个参数时,它可以让您省略括号:
getListForID(12)
.Success( { /* Success block */ } )
.Failure( { /* Failure block */ } )
这使得API背后的代码结构更加清晰:
getListForID
的 return 值必须是一个对象- 对象必须有两个函数
Success
和Failure
* Success
和Failure
都需要带一个闭包类型的参数Success
和Failure
都需要returnself
* 对象可能只有 Success
函数,而 return 一个具有单个 Failure
函数的不同对象,但是你将无法重新排序 Success
和 Failure
处理程序,或完全删除 Success
处理程序。
为了扩展
首先,您必须定义一个新的 class 来表示 'result handler'。这就是您的 success
和 failure
函数将传递的内容,允许您添加多个尾随闭包来构成您的完成块逻辑。你会希望它看起来像这样:
class ResultHandler {
typealias SuccessClosure = RequestHandler.Output->Void
typealias FailureClosure = Void->Void
// the success and failure callback arrays
private var _successes = [SuccessClosure]()
private var _failures = [FailureClosure]()
/// Invoke all the stored callbacks with a given callback result
func invokeCallbacks(result:RequestHandler.Result) {
switch result {
case .Success(let output): _successes.forEach{[=10=](output)}
case .Failure: _failures.forEach{[=10=]()}
}
}
// remove all callbacks – could call this from within invokeCallbacks
// depending on the re-usability of the class
func removeAllCallbacks() {
_successes.removeAll()
_failures.removeAll()
}
/// appends a new success callback to the result handler's successes array
func success(closure:SuccessClosure) -> Self {
_successes.append(closure)
return self
}
/// appends a new failure callback to the result handler's failures array
func failure(closure:FailureClosure) -> Self {
_failures.append(closure)
return self
}
}
这将允许您定义要在完成时执行的多个成功或失败闭包。如果您实际上不需要多个闭包的容量,那么您可以通过剥离数组来简化 class —— 而是只跟踪最后添加的成功和失败完成块。
现在您所要做的就是定义一个函数,该函数生成一个新的 ResultHandler
实例,然后执行给定的异步请求,并在完成时调用 invokeCallbacks
方法:
func doRequest(input:Input) -> ResultHandler {
let resultHandler = ResultHandler()
doSomethingAsynchronous(resultHandler.invokeCallbacks)
return resultHandler
}
现在你可以这样称呼它了:
doRequest(input).success {result in
print("success, with:", result)
}.failure {
print("fail :(")
}
唯一需要注意的是您的 doSomethingAsynchronous
函数必须将其完成块分派回主线程,以确保线程安全。
完整项目(添加了使用示例):https://github.com/hamishknight/Callback-Closure-Chaining