3

在处理执行 Promise 时可能抛出的错误时,在使用 recover 时遇到一个奇怪的错误。

如果在恢复块中有多个语句,则将 .recover 与 .then 链接会导致编译。

在恢复块中使用单个语句并单独恢复(promise.recover{} 没有 then 有效)

附上单语句恢复(有效)和多语句恢复(引发编译错误并显示消息的屏幕截图:Ambiguous use of recover(on:__:)

任何有关如何调试的帮助将不胜感激。

在此处输入图像描述 在此处输入图像描述

4

2 回答 2

3

recover可以返回一个 Promise。如果您的恢复块中只有 1 条语句,那么编译器不会抱怨,因为只有一行可能返回任何内容。当您添加第二条语句时,编译器无法推断出哪一行返回了某些内容。明确指出您正在返回 Void 是一种可能的解决方法,假设您不打算实际返回任何内容。

func getNext() {
    taskGroup.getNext().then { data in
        self.initViewWithTask(data as! Task)
    }.recover { error -> Void in
        print("in recover")
        print("in recover 2")
    }
}

解释:

这四个示例在功能上相同,将One : Two : Three在最后打印。第一个示例中的闭包明确说明它将接收什么参数+类型以及返回什么类型。每个后续示例对正在发生的事情越来越不明确,因此编译器必须推断/推断正在发生的事情。编译器可以弄清楚发生了什么,因为这些示例相当简单。

firstly {
    return Promise("One")
}.then { (result1: String) -> Promise<String> in
    return Promise("\(result1) : Two")
}.then { (result2: String) -> Promise<String> in
    return Promise("\(result2) : Three")
}.then { (result3: String) -> Void in
    print(result3)
    return
}

firstly {
    Promise("One")
}.then { (result1: String) -> Promise<String> in
    Promise("\(result1) : Two")
}.then { (result2: String) -> Promise<String> in
    Promise("\(result2) : Three")
}.then { (result3: String) -> Void in
    print(result3)
}

firstly {
    Promise("One")
}.then { result1 -> Promise<String> in
    Promise("\(result1) : Two")
}.then { result2 -> Promise<String> in
    Promise("\(result2) : Three")
}.then { result3 -> Void in
    print(result3)
}

firstly {
    Promise("One")
}.then { result1 in
    Promise("\(result1) : Two")
}.then { result2 in
    Promise("\(result2) : Three")
}.then { result3 in
    print(result3)
}

现在在第一个闭包中添加第二行。编译器会感到困惑,因为它不知道要返回什么。它可能是999One。即使像您那样添加一个简单的打印语句也会使编译器感到困惑并且它会抱怨ambiguous something. 因此,要么编译器需要变得更智能(在简单的 print 语句的情况下当然可以),要么你需要更明确地了解正在发生的事情。

// ambiguous
firstly {
    Promise(999)
    Promise("One")
}.then { result1 in
    Promise("\(result1) : Two")
}.then { result2 in
    Promise("\(result2) : Three")
}.then { result3 in
    print(result3)
}

// clear
firstly {
    Promise(999)
    return Promise("One")
}.then { (result1: String) in
    Promise("\(result1) : Two")
}.then { result2 in
    Promise("\(result2) : Three")
}.then { result3 in
    print(result3)
}

作为旁注......这实际上与 Pr​​omiseKit 没有任何关系。这些示例可以在没有 PromiseKit 的情况下编写。现在只是了解 Swift 编译器如何解释闭包。

于 2015-12-28T23:25:39.647 回答
0

使用 PromiseKit 6.11.0 (Swift 5.1/Xcode 11.1)如果你不想从关闭中返回,你应该使用done而不是。在这种情况下,你不会得到"Ambiguous use of recover"thenThenable

taskGroup.getNextTask().done { data in
    self.initViewWithTask(data as! Task)
}.recover { error in
    NSLog("in recover")
}
于 2019-10-10T09:44:07.613 回答