PromiseKit 6.0将捕获的错误传递给调用者

时间:2018-04-13 09:01:59

标签: ios swift promise promisekit

根据迁移指南,PromiseKit 6.x改变了他关于catch块的政策。在PMK 4 catch返回了附加的承诺。现在catch是一个链终结者。我明白为什么要做出这些改变但是......

在我的代码库中(与PK4连接)我从catch返回promise中获得了一些优势。

func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
    synchronizationService.stopAllRunningSingleSynchronizations()

    return
        authorizationService.save(serverAddress: address, andPort: port)
            .then {
                self.synchronizationService.startSingleFullSynchronization()
            }
            .then {
                self.authorizationService.markAsServerSynced()
            }
            .catch { error in
                log.error(error)
                _ = self.authorizationService.markAsServerUnsynced()
            }
}

在这个函数中,我做了一些逻辑,在某些情况下可以使用。如果出现错误catch阻塞应该做出一些逻辑,但我还想向loginAndSync函数调用者发送此承诺的结果(履行或拒绝)。上面的函数可以通过ViewController调用,在ViewController中我想显示例如Error或Success Dialog。

这是我需要两个catch es用于一个Promise链的原因。一个用于authorizationService,另一个用于UI

PromiseKit6中是否有解决方法来实现这一目标?

修改

我找到了两个解决方案(解决方法)。我创建了两个将它们分开的答案。未来的读者可以决定哪一个更好或者提供新的。

2 个答案:

答案 0 :(得分:2)

我发现(IMO)更好的解决方法。 PromiseKit6引入了非常方便的方法tap。我试过用它来解决我的问题。

func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
    synchronizationService.stopAllRunningSingleSynchronizations()

    return authorizationService.save(serverAddress: address, andPort: port)
        .then {
            self.synchronizationService.startSingleFullSynchronization()
        }
        .then {
            self.authorizationService.markAsServerSynced()
        }
        .tap { result in
            switch result {
            case .rejected(let error):
                log.error(error)
                _ = self.authorizationService.markAsServerUnsynced()
            default: break
            }
        }
        .done {
            self.coordinatorDelegate?.handleLoginServerSuccess()
        }
}

对于doc:

  

tap为您提供链的当前结果,因此如果链成功或者失败则调用

因此,我可以为终止链的Promise whit的当前状态提供自定义错误处理。承诺可以发送给发件人,我可以通过tap发送另一个catch或终止链。

答案 1 :(得分:0)

我把我的Promise链包装在另一个Promise中:

func loginAndSync(withServerAddress address: String, port: String) -> Promise<()> {
    synchronizationService.stopAllRunningSingleSynchronizations()

    return Promise { seal in
        authorizationService.save(serverAddress: address, andPort: port)
            .then {
                self.synchronizationService.startSingleFullSynchronization()
            }
            .then {
                self.authorizationService.markAsServerSynced()
            }
            .done {
                self.coordinatorDelegate?.handleLoginServerSuccess()
                seal.fulfill(())
            }
            .catch {
                log.error($0)
                _ = self.authorizationService.markAsServerUnsynced()
                seal.reject($0)
            }
    }
}

它应该有效,但我不知道这是一个好方法。