要简短地讲故事'说我有一个运营商定义:
infix operator <~ {
associativity left
precedence 160
}
让我们说我使用这个操作符做两个对象之间的某些工作,所以我已经定义了这样的函数:
func <~ <T: FirstProtocol, U:SecondProtocol>(lhs: T, rhs: U) {
//async request
}
现在我们无法返回任何内容,因为运算符函数正在执行异步工作,我们也无法使用更多参数来进行闭包。因为异步函数可能会运行几秒钟,所以我需要一个在异步任务完成时运行的回调。问题是你是否可以使用具有异步功能的运算符?我尝试了各种解决方案,但似乎都没有。
完美的解决方案如下所示:
something <~ somethingElse {
error in
//async call finished
}
答案 0 :(得分:1)
如果您愿意设置一些脚手架,您可以完成此任务。没有办法可以开箱即用。
让我们考虑如何在没有操作员的情况下这样做。我们会有一个操作队列,每个完成后我们都会添加下一个操作。并且每个操作都应该在完成后通知队列。
因此,运营商只负责将操作添加到队列中。如果你想要一个更复杂的实现,请查看Swift的任何Promises库。我试图将这个概念的基本工作实现放在一起:
var queue = NSOperationQueue()
infix operator <~ {
associativity left
precedence 160
}
struct QueuedOperation
{
var operation : NSBlockOperation
}
func <~ (first: ()->(), second:()->())->QueuedOperation {
let operationOne = NSBlockOperation(block: first)
let operationTwo = NSBlockOperation(block: second)
operationTwo.addDependency(operationOne)
queue.addOperation(operationOne)
queue.addOperation(operationTwo)
return QueuedOperation(operation: operationTwo)
}
func <~ (first : QueuedOperation, second:()->())->QueuedOperation {
let operationTwo = NSBlockOperation(block: second)
operationTwo.addDependency(first.operation)
queue.addOperation(operationTwo)
return QueuedOperation(operation: operationTwo)
}
_ = {
sleep(2)
print("First")
} <~ {
sleep(4)
print("Second")
} <~ {
sleep(8)
print("Third")
}
所以它的工作原理如下:
操作1&lt;〜操作2&lt;〜操作3
Operation1&lt;〜Operation2
调用第一个将Operation1和&amp;队列上的Operation2并将Operation1添加为Operation2的依赖项。我们从此返回一个QueuedOperation包装Operation2,因为当我们向前链接时,后续的一个依赖于Operation2但是Operation2将再次排队。
返回不同的类型并调度到具有不同类型签名的函数允许我们这样做。
答案 1 :(得分:1)
不幸的是,something <~ somethingElse { err in ... }
是不可能的,因为编译器将其解释为something <~ (somethingElse({ err in ... }))
。
至少,你必须(something <~ somethingElse) { err in ... }
。在游乐场试试这个:
import Foundation
infix operator <~ {
associativity left
precedence 160
}
func <~(lhs: Int, rhs: Int) -> ((Int) -> Void) -> Void {
return { callback in
dispatch_async(dispatch_get_main_queue()) {
callback(lhs + rhs)
}
}
}
let a = 1
let b = 2
(a <~ b) { result in
println("OK: \(result)")
}
dispatch_main()