在这里,我想实现'承诺'像块。但我无法设置块的结果。
这里我有两个挑战:
我正在尝试实现一个简单的Promise示例
来自名字和姓氏的字符串。
我想多次打电话给“then”。
首先我想从两个网站上都查到全名。
然后转换成大写。
然后转换成小写。
……等等(意思是说在一些任务中有多个“then”条件。)
我怎样才能做到多次?
这是我的例子。

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)
}

最佳答案

首先,要链接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)
    }
}

如果您愿意,可以对errorfinally执行类似的操作。
对于您现有的代码,在解决了承诺之后,您附加了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类型中,只要记住这一点(并使其显著简化……)就可以了

09-25 18:44
查看更多