在这里,我想实现类似于块的“承诺”。但是我无法为块设置结果。
这里我有2个挑战:
我如何多次取得成就?
这是我的例子。
class Promise<T> {
private var resultHandler : ((_ result:T)->())?
private var errorHandler : ((_ error:String)->())?
private var final : (()->())?
func resolve(_ value: T) {
resultHandler?(value)
final?()
}
func reject(_ value: String) {
errorHandler?(value)
final?()
}
func then(_ block:@escaping (_ result:T)->()) {
resultHandler = block
}
func error(_ block:@escaping (_ result:String)->()) {
errorHandler = block
}
func finally(_ block:@escaping ()->()) {
final = block
}
}
func getFullName(firstname: String, lastname: String) -> Promise<String> {
let p = Promise<String>()
if firstname.count > 0 && lastname.count > 0 {
let name = firstname + " " + lastname
p.resolve(name)
}
else {
print("--")
p.reject("Firstname and Lastname can't be empty" )
}
return p
}
let p = getFullName(firstname: "Alen", lastname: "Stel")
p.then { (name) in
print("Name", name)
}
答案 0 :(得分:1)
首先,要链接then
之类的东西,您需要链接处理程序,例如:
func then(block: @escaping (T)->()) {
if let oldHandler = resultHandler {
resultHandler = {
oldHandler($0)
block($0)
}
} else {
resultHandler = block
}
}
或者您可以通过将resultHandler
设为非可选来简化操作:
private var resultHandler: (T)->() = {}
...
func then(block: @escaping (T)->()) {
resultHandler = { [oldHandler] in
oldHandler($0)
block($0)
}
}
如果愿意,您可以执行与error
和finally
类似的操作。
对于您现有的代码,您将在解决承诺后附加then
。您必须处理这种情况。您可以使用枚举State
(例如.pending
,.resolved
,.error
)来完成此操作,也可以只使用一些变量,例如:
private var value: T?
...
func then(block: @escaping (T)->()) {
if let value = value {
block(value)
} else {
resultHandler = { [oldHandler] in
oldHandler($0)
block($0)
}
}
func resolve(_ value: T) {
self.value = value
resultHandler(value)
resultHandler = {}
final()
final = {}
}
(或者类似的东西。我还没有完全测试过。)
请记住,这都是线程不安全的,因此您必须小心添加.then
子句或在不同的队列上进行解析,但是只要保留该类型,这对于简单的Promise类型就可以了记住(并使其变得非常简单。...)